Proste kodowanie instrukcji
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
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