Proste kodowanie instrukcji

Oct 07 2020

Weźmy następującą instrukcję montażu:

add    %cl,%bl

Jest to kodowane jako: 00 cblub 00000000 11001011binarnie. Kładzenie cbdo bitfields Modr / m, to wygląda:

  1   1   0   0   1   0  1   1
+---+---+---+---+---+---+---+---+
|  mod  |    reg    |    r/m    |
+---+---+---+---+---+---+---+---+

I patrząc na pole rejestrowe tutaj otrzymujemy:

  • mod: 11(Tryb adresowania rejestru)
  • reg: 001(rejestr cl)
  • r / m: 011(rejestr bl)

Uważam, że 000000dsjest to addinstrukcja, a d=s=0ponieważ wszystkie są rejestrami. Czy to poprawne zrozumienie sposobu zakodowania tej instrukcji? Ponadto w przypadku schematu „pełnego kodowania” poniższe wartości byłyby dokładne (w bajtach, a nie w bitach):

[empty]         0x0         0b11001011     [empty]        [empty]          [empty]
_ _ _ _        _ _             _              _           _ _ _ _          _ _ _ _
Prefix      Instruction    Mod-reg-r/m      Scale       displacement      immediate

Czy jest coś, czego mi brakuje podczas próby „rozszyfrowania” instrukcji?

Odpowiedzi

2 PeterCordes Oct 08 2020 at 04:14

Tak, wygląda dobrze.

Ogólny wzór (dla instrukcji „starszego typu” ALU, które sięgają do 8086) do kodowania op r/m, rvs. op r, r/mi 8-bitowe vs. 16/32 bit używa niska 2 bity bajtu rozkazu w regularny wzór, ale nie ma takiej potrzeby polegać na tym.

Firma Intel w pełni dokumentuje dokładnie to, co dzieje się przy każdym kodowaniu każdej instrukcji w podręczniku vol.2. Zobacz addna przykład kolumnę Op / En i tabelę kodowania operandów . (Zobacz teżhttps://ref.x86asm.net/coder64.htmktóry również określa, który operand jest którym dla każdego kodu operacji). Oba informują, które opkody pobierają bajt ModRM, a które nie.

Te oczywiście używają kolejności składni Intela. Robisz swoje życie bardziej skomplikowanym, próbując postępować zgodnie z instrukcjami i samouczkami, używając składni AT&T, która odwraca kolejność listy operandów w porównaniu z podręcznikami Intel i AMD.

np. 00 /rjest wymienione jako MRkodowanie operandów, które z tabeli, które widzimy, to operand 1 = ModRM:r/m (r, w), więc jest odczytywane i zapisywane oraz kodowane przez r/mpole. operand 2 = ModRM:reg (r), więc jest to źródło tylko do odczytu zakodowane przez regpole.

Zabawny fakt: 00 00jest add [rax], allub AT&Tadd %al, (%rax)

Zauważ, że możesz poprosić GAS o wybranie jednego z kodowań: różnice kodu operacji x86 XOR

{load}  add    %cl,%bl        # 02 d9
{store} add    %cl,%bl        # 00 cb

Zobacz także Różnica między MOV r / m8, r8 i MOV r8, r / m8