Kurs programowania w asemblerze
Słowniczek
Spis haseł głównych:- Blok DTA
- Blok FCB
- Blok PSP
- Kod ASCIIZ
- Kod BCD
- U2 - liczby ujemne
- Floating point numbers (Liczby zmiennopozycyjne)
Kod BCD
Kod BCD (Binary Coded Decimal) jest to sposób zapisania liczb całkowitych bez znaku, dwucyfrowych w jednym bajcie. Polega on na tym, iż cztery pierwsze bity tego bajta przypadają na pierwszą cyfrę, natomiast kolejne cztery na drugą. W programie do rozkodowania tego zapisu możemy użyć ciągu rozkazów:
Liczba w kodzie BCD jest zapisana w rejestrze AL
MOV BL,AL AND BL,0FH ADD BL,'0' SHR AL,4 ADD AL,'0'
W rejestrach AL i BL znajdują się teraz kody ASCII cyfr po odkodowaniu.
U2 - liczby ujemne
Do zapisu liczb ujemnych w asemblerze stosuje się tzw. kod uzupełnień do dwóch (U2 - U-two's complement). Tyczy się to tylko liczb ujemnych. Dodatnie w U2 zapisuje bez zmian.
By zmienić liczbę dodatnią na ujemną wykonujemy szereg operacji: negujemy wszystkie bity, dodajemy do wszystkiego 1, np:
1. mamy liczbę 00101101b
2. negujemy - 11010010b
3. dodajemy 1 - 11010011b
Liczba 45d=00101101b, a liczba -45d=11010011b
Dana liczba może być liczbą dodatnią lub ujemną. To jak zostanie potraktowana zależy od programisty.
Floating point numbers (Liczby zmiennopozycyjne)
Procesor standardowo pracuje tylko na liczbach całkowitych, dlatego by obsługiwać liczby rzeczywiste trzeba użyć tzw. zmiennopozycyjny zapis liczb. Dostępne są cztery główne podtypy: single, real, exendet i double. Liczby zapisany w każdym z tych typów różnią się zakresem oraz ilością zajmowanych bajtów pamięci.
Każdą liczbę można zapisać jako:m*10c (gdzie m-mantysa, c - cecha i 1<c<10). Tak samo każda liczba może zostać zapisana jako: m*2c (1<m<3, c jest całkowite), dzięki czemu możemy już operować na liczbach binarnych. Np. liczba 243.75d=11110011.11b. Do wyznaczenia jej mantysy trzeba odpowiednio pomnożyć lub podzielić liczbę przez 2 (przesunąć w lewo lub w prawo - SHL, SHR), aż otrzymamy po lewej stronie liczbę 1. W naszym wypadku m=1.11100111b. Cechę naszej liczby stanowi wówczas liczba wykonanych przesunięć. Cecha posiada znak zależny od kierunku przesuwania "+" - lewo, "-" prawo. U nas c=+7. Naszą liczbę możemy więc zapisać jako: 1.11100111*2111
Pokaże teraz jak zapisać liczbę typu single. Jest to typ 32 bitwy, czyli zajmuje 4 bajty. Został on podzielony na trzy części. Pierwsza część (licząc od lewej) to jeden bit, który określa rodzaj znaku, tzn. jeżeli jest równy 1, to znaczy, że cecha jest ujemna, a jeśli 0, dodatnia. Następna część to 8 bitów przeznaczonych na cechę liczby. W kolejnej trzeciej części (23 bity) zapisana jest mantysa. W sumie wykorzystujemy całe 32 bity naszej liczby.
Zajmijmy się teraz kodowaniem. Na początku musimy wyznaczyć mantysę i cechę. Gdy to już zrobimy przystępujemy do zapisu tej liczby. Najpierw ustawiamy odpowiednio znak (bit pierwszy od lewej). Następnie zapisujemy cechę. Przyjęto zasadę, że zwiększamy ją o 127, w celu uwzględnienia jej znaku (nie stosujemy tutaj U2). Dalej zapisujemy mantysę. Ponieważ zaczyna się ona zawsze od 1 i zapisanie tego byłoby zbędne, przyjmuje się, że zapisujemy mantysę bez jedynki. W naszym przypadku wygląda to tak:
- ustawiamy bit znaku na 0 - dodatnia
- zapisujemy manyse: 11100111100000000000000b (łącznie 23 bity)
- zapisujemy cechę, czyli 7+127=10000110b
Nasza liczba 243.75 zakodowana wygląda tak: 01000011011100111100000000000000
Blok FCB
File Control Block - Blok Opisu Pliku. W pierwszych wersjach systemu był on 34-bajtowy. Może mieć dwie wersje: normalną i rozszerzoną. Blok ma następującą postać:
| Offset | Rozmiar | Znaczenie |
|---|---|---|
| -07H | 1 | Wskaźnik początku rozszerzonego FCB zawsze 0FFH |
| -06H | 5 | Zarezerwowane |
| -01H | 1 | Atrybuty pliku |
| Start zwykłego FCB | ||
| 00H | 1 | Numer dysku 1=A, 2-B itd. Jeśli używasz FCB do otwierania pliku to możesz w to miejsce wstawić 0 jako numer bieżącego dysku, a system sam wstawi odpowiednią wartość |
| 01H | 8 | Nazwa pliku (nazwa urządzenia). Nazwa odnosi się do bieżącego katalogu. |
| 09H | 3 | Rozszerzenie nazwy |
| 0CH | 2 | Numer bloku - wspólnie z polem przesunięcia rekordu wskazują na adres aktualnego rekordu. Blok jest grupą 128 rekordów. Przy otwieraniu pole to zostanie wyzerowane. |
| 0EH | 2 | Rozmiar rekordu logicznego w pliku. Standardowo ustawiony na 80H. |
| 10H | 4 | Rozmiar pliku w bajtach |
| 14H | 2 | Data ostatniej modyfikacji 15H-RRRRRRRM MMMDDDDD-14H R - rok licząc od 1980 M - miesiąc D - dzień |
| 16H | 2 | Czas ostatniej modyfikacji: 17H-GGGGGMMM MMMSSSSS-16H G - godzina M - minuta S - sekunda |
| 18H | 8 | Zarezerwowane |
| 20H | 1 | Przesunięcie rekordu - wskazuje na pozycję bieżącego rekordu w bloku. |
| 21H | 4 | Numer rekordu liczony od początku pliku. |
Kod ASCIIZ
Jest to kod, który jest zakończony znakiem o kodzie ASCII 0, np. nazwa pliku w kodzie ASCIIZ może wyglądać tak:
Nazwa DB "AUTOEXEC.BAT",0
Blok DTA
Disk Transfer Adres - jest to bufor roboczy do operacji dyskowych. Służy do przeprowadzania operacji dyskowych, które zawsze wykorzystują ten obszar jako jedną ze stron przesyłania danych lub do zapisu informacji odczytanych z dysku. Przed rozpoczęciem pracy procesu system przydziela w przedrostku PSP komórki 80H-FFH jako standardowy bufor roboczy dla danego procesu. DTA jest strukturą lokalną, tzn. że dla każdego procesu może znajdować się w innym miejscu.
Blok PSP
| Adres | Opis |
|---|---|
| 00-01 | Kod rozkazu INT 21H (CD21) |
| 02-03 | Adres segmentu pamięci niedostępnej dla programu |
| 04 | Nie używane przez DOS, używane wewnętrznie przez OS/2 |
| 05-09 | Dalekie odwołanie do systemu DOS (rozkaz wywołania dalekiej procedury) |
| 06-07 | Rozmiar dostępnej pamięci w segmencie |
| 0A-0D | Zapamiętywany adres końca programu (INT 22H) |
| 0E-11 | Adres programu obsługi CTRL+BREAK (INT 23H) |
| 12-15 | Adres programu obsługi błędów krytycznych (INT 24H) |
| 16-17 | Adres do segmentów pamięci, gdzie znajduje się blok PSP programu rodzicielskiego (interpretator poleceń modyfikuje to pole i wstawia tam adres swojego PSP) |
| 18-2C | Tablica plików obsługiwanych przez proces JFT (ang. Job File Table); każdy element tablicy zawiera indeks wskazujący na element SFT (ang. System File Table) opisujący wszystkie otwarte w systemie pliki lub też wartość FF, jeżeli element nie jest używany |
| 2C-2D | Adres segmentu pamięci w którym znajduje się otoczenie programu, zawierające definicje zmiennych środowiskowych systemu DOS, np. PATH. Każdy element oddzielony jest znakiem NUL (00); funkcja 4B rozszerza otoczenie programu poprzez dodanie jednego słowa określającego ilość dodatkowych łańcuchów ASCIIZ, a następnie umieszcza dalej nazwę uruchamianego programu. Umożliwia to procesowi dotarcie do pliku zawierającego kod programu |
| 2E-31 | Zapamiętane wartości SS:SP aktualnego procesu |
| 32-33 | Liczba elementów tablicy JFT (standardowo 20) |
| 34-37 | Daleki wskaźnik do poprzedniego bloku wstępnego PSP |
| 3C-4F | Pola wykorzystywane wewnętrznie przez różne systemy operacyjne |
| 50-52 | Kod rozkazów: INT 21H RETF |
| 53-54 | Nie używane |
| 55-5B | Nie używane |
| 5C-6B | Standardowy blok opisu pliku FCB1 |
| 6C-7B | Standardowy blok opisu pliku FCB2 |
| 7C-7F | Nie używane |
| 80-FF | Bufor transmisji dyskowych DTA. Po uruchomieniu programu zawiera parametry podane w linii poleceń, zakończony znakiem CR (0D). Bajt pod adresem 80 określa długość wiersza wejściowego (bez znaku CR) |
