Tabele Kodowania Rozkazów x86 (16-bit AT&T)
Analiza rozkazu x86 (16-bitowa składnia AT&T) rozpoczyna się od weryfikacji początkowych bitów pierwszego bajtu, co determinuje format rozkazu oraz jego długość:
- Rozkazy 1-bajtowe z rejestrem:
- 01000xxx: INC rejestr (np. inc%BX), długość: 1 bajt.
- 01001xxx: DEC rejestr (np. dec%CX), długość: 1 bajt.
- 01010xxx: PUSH rejestr (np. push%DX), długość: 1 bajt.
- 01011xxx: POP rejestr (np. pop%AX), długość: 1 bajt.
- Rozkazy 1-bajtowe bez operandu:
- 10010000: NOP (No Operation), długość: 1 bajt.
- 11000011: RET (Return), długość: 1 bajt.
- 11111000: CLC (Clear Carry Flag), długość: 1 bajt.
- Rozkazy 2-bajtowe (typu rejestr-rejestr):
- 000000DW: ADD (np. add%BX,%CX), długość: 2 bajty.
- 001010DW: SUB (np. sub%DX,%BX), długość: 2 bajty.
- 000010DW: OR (np. or%CX,%DX), długość: 2 bajty.
- 001000DW: AND (np. and%AX,%BX), długość: 2 bajty.
- 001100DW: XOR (np. xor%BX,%CX), długość: 2 bajty.
- 001110DW: CMP (np. cmp%AX,%BX), długość: 2 bajty.
- 100010DW: MOV (np. mov%CX,%DX), długość: 2 bajty.
- 100001DW: XCHG (np. xchg%BX,%CX), długość: 2 bajty.
- Rozkazy rozszerzone:
- 1111111W: Rozszerzony INC/DEC pamięci, długość: 2 do 4 bajtów (np. inc0x20(%BX)).
- 1111011W: Rozszerzone operacje MUL, DIV, NEG, NOT, długość: 2 lub więcej bajtów (np. mul%BX).
- 100000SW: Operacje z operandem natychmiastowym, długość: 3 do 6 bajtów (np. add$5,%BX).
Kody rejestrów w polach REG i R/M
Kodowanie rejestrów zależy od wartości bitu szerokości W oraz kontekstu pola (REG lub R/M przy mod=11).
Tryby adresowania pamięci (Pole MOD i R/M)
Jeśli pole MOD=11, połączenie MOD oraz R/M określa tryb adresowania pamięci zamiast bezpośredniego wyboru rejestru.
- Kombinacje pola R/M dla poszczególnych wartości MOD:
- 000:
- mod=00→[BX+SI]
- mod=01→[BX+SI+disp8]
- mod=10→[BX+SI+disp16]
- 001:
- mod=00→[BX+DI]
- mod=01→[BX+DI+disp8]
- mod=10→[BX+DI+disp16]
- 010:
- mod=00→[BP+SI]
- mod=01→[BP+SI+disp8]
- mod=10→[BP+SI+disp16]
- 011:
- mod=00→[BP+DI]
- mod=01→[BP+DI+disp8]
- mod=10→[BP+DI+disp16]
- 100:
- mod=00→[SI]
- mod=01→[SI+disp8]
- mod=10→[SI+disp16]
- 101:
- mod=00→[DI]
- mod=01→[DI+disp8]
- mod=10→[DI+disp16]
- 110:
- mod=00→disp16 (Adres bezpośredni - przypadek specjalny, brak rejestru bazowego)
- mod=01→[BP+disp8]
- mod=10→[BP+disp16]
- 111:
- mod=00→[BX]
- mod=01→[BX+disp8]
- mod=10→[BX+disp16]
- Adresowanie rejestrowe (mod=11): Rejestr wskazany przez R/M (według tabeli rejestrów dla W=0 lub W=1).
Rozszerzone kody operacji w bajcie 2 (Pole OP)
W niektórych formatach (np. gdy bajt 1 kończy się prefiksem rozszerzenia), 3-bitowe pole REG w drugim bajcie służy jako rozszerzenie kodu operacji (pole op).
Dla bajtu 1 = 1111111x (INC/DEC/CALL/JMP/PUSH memoriałowe):
- 000: INC
- 001: DEC
- 010: CALL (pośredni)
- 011: CALL (daleki)
- 100: JMP (pośredni)
- 101: JMP (daleki)
- 110: PUSH
- 111: Rezerwacja
Dla bajtu 1 = 1111011x (Operacje arytmetyczne i logiczne):
- 000: TEST (z operandem natychmiastowym)
- 001: Rezerwacja
- 010: NOT
- 011: NEG
- 100: MUL (bez znaku)
- 101: IMUL (ze znakiem)
- 110: DIV (bez znaku)
- 111: IDIV (ze znakiem)
Dla bajtu 1 = 100000xx (Operacje z operandem natychmiastowym):
- 000: ADD
- 001: OR
- 010: ADC
- 011: SBB
- 100: AND
- 101: SUB
- 110: XOR
- 111: CMP
Znaczenie pól bitowych D, W oraz S
- Bit W (Width):
- W=0: Operandy 8-bitowe (np. AL,BL,CL,DL,AH,BH,CH,DH).
- W=1: Operandy 16-bitowe (np. AX,BX,CX,DX,SP,BP,SI,DI).
- Bit D (Direction):
- D=0: Pole REG określa źródło (SOURCE), a pole R/M określa cel (DESTINATION).
- D=1: Pole R/M określa źródło (SOURCE), a pole REG określa cel (DESTINATION).
- Bit S (Sign-extend):
- S=0: Pełny operand natychmiastowy (8 bitów dla W=0, 16 bitów dla W=1).
- S=1: 8-bitowy operand natychmiastowy z rozszerzeniem znaku do 16 bitów (stosowane przy W=1).
- 1-bajtowy bez operandu:
- Budowa: Kod operacji (8 bitów).
- Przykład: nop=10010000, ret=11000011, clc=11111000.
- 1-bajtowy z rejestrem (INC/DEC/PUSH/POP):
- Budowa: Kod operacji (5 bitów) + reg (3 bity).
- Przykład: inc%BX=01000011, dec%CX=01001001, push%DX=01010010, pop%AX=01011000.
- 2-bajtowy rejestr-rejestr:
- Bajt 1: op(6bitoˊw)DW.
- Bajt 2: 11reg(3bity)r/m(3bity).
- Przykład: add%BX,%CX=0000000111011001, sub%DL,%BL=0010100011010011.
- 2-bajtowy rejestr + pamięć (bez przemieszczenia):
- Bajt 1: op(6bitoˊw)DW.
- Bajt 2: 00reg(3bity)r/m(3bity).
- Przykład: mov(%BX),%CL=1000101000001111.
- 3-bajtowy rejestr + pamięć (8-bit przemieszczenie):
- Bajt 1: op(6bitoˊw)DW.
- Bajt 2: 01reg(3bity)r/m(3bity).
- Bajt 3: disp8.
- Przykład: and4(%BP),%CX=001000110100111000000100.
- 4-bajtowy rejestr + pamięć (16-bit przemieszczenie):
- Bajt 1: op(6bitoˊw)DW.
- Bajt 2: 10reg(3bity)r/m(3bity).
- Bajty 3-4: disp16 (kolejność LSB, MSB).
- Przykład: or0x5000(%BX),%CX=00001011100011110000000001010000.
- 3-bajtowy rejestr + natychmiastowy (8-bit data):
- Bajt 1: 100000SW.
- Bajt 2: 11op(3bity)r/m(3bity).
- Bajt 3: data8.
- Przykład: add$5,%BX=100000111100001100000101.
- 4-bajtowy rejestr + natychmiastowy (16-bit data):
- Bajt 1: 10000001.
- Bajt 2: 11op(3bity)r/m(3bity).
- Bajty 3-4: data16 (kolejność LSB, MSB).
- Przykład: add$0x400,%BX=10000001110000110000000000000100.
Algorytm dekodowania rozkazów — krok po kroku
Procedura zamiany binarnego kodu na instrukcję w składni AT&T przebiega w następujący sposób:
- KROK 1: Pobierz bajt 1 i zamień jego postać na binarną.
- KROK 2: Zidentyfikuj format na podstawie pierwszych bitów bajtu 1.
- 01000xxx…01011xxx: Instrukcje 1-bajtowe (INC, DEC, PUSH, POP), rejestr zakodowany w ostatnich 3 bitach.
- 10010000: NOP.
- 11000011: RET.
- 1111111x lub 1111011x: Przejdź do analizy bajtu 2 (rozszerzone operacje).
- 100000xx: Operacja natychmiastowa (czytaj bajt 2 oraz dane).
- Pozostałe: Standardowy 2-bajtowy rozkaz (bit7−2=op, bit1=D, bit0=W).
- KROK 3: Pobierz bajt 2 i podziel go na pola: mod(2bity), reg(3bity), r/m(3bity).
- KROK 4: Zinterpretuj pole mod:
- mod=11: Pole r/m wskazuje na rejestr.
- mod=00: Pole r/m wskazuje na adres bazowy w pamięci; jeśli r/m=110, czytaj 2 bajty przemieszczenia (disp16).
- mod=01: Pole r/m wskazuje na adres bazowy + czytaj 1 bajt przemieszczenia (disp8).
- mod=10: Pole r/m wskazuje na adres bazowy + czytaj 2 bajty przemieszczenia (disp16).
- KROK 5: Ustal kierunek operacji na podstawie bitu D:
- D=0→ rejestr (reg) to źródło, a r/m (rejestr lub pamięć) to cel.
- D=1→r/m (rejestr lub pamięć) to źródło, a rejestr (reg) to cel.
- KROK 6: Złóż końcową instrukcję w formacie AT&T:
nazwa_instrukcji źródło, cel.
Opracowano na podstawie kursu Architektury Komputerów — Collegium Da Vinci, prowadzonego przez dr. D. Wawrzyniaka.