2015-09-08 7 views
5

Gram z x86 ISA, kiedy spróbowałem użyć nasm przekonwertować niektóre instrukcje montażu do instrukcji maszyny, znalazłem coś ciekawego.sama instrukcja montażu, ale inna instrukcja obsługi maszyny

mov [0x3412],al 
mov [0x3412], bl 
mov [0x3412], cl 
mov [0x3412], dl 

1 00000000 A21234     mov [0x3412], al 
2 00000003 881E1234    mov [0x3412], bl 
3 00000007 880E1234    mov [0x3412], cl 
4 0000000B 88161234    mov [0x3412], dl 

Jak widać, mov [0x3412], al jest wyjątkiem od reguły. Zauważyłem również, że mov [0x3412], al odwzorowuje dwie różne instrukcje maszyny.

[email protected]:~/asm$ ndisasm 123 
00000000 88061234   mov [0x3412],al 
00000004 A21234   mov [0x3412],al 

Czy oprócz tej instrukcji specjalnej istnieje inne odwzorowanie instrukcji złożenia na więcej niż jedną instrukcję maszyny w x86?

+13

Natknąłeś się na artefakt z projektu Intela o 808X. AX to rejestr 16-bitowy, ale Intel wykonał AX (lub 8/bitową wersję AH i AL) dla niektórych operacji. Intel widział rejestr AX jako akumulator. AX (i AH, AL) mają specjalne kodowanie dla niektórych instrukcji (zwykle o jeden bajt mniej). Możesz wybrać krótszą lub dłuższą instrukcję (krótsza jest lepsza dla ograniczonej pamięci). Oprócz MOV, AX/AH/AL posiada specjalne kodowanie dla ADC, ADD, AND, CMP, OR, SBB, SUB, TEST, XOR. –

+4

@MichaelPetch: to jest właściwie odpowiedź, a nie zwykły komentarz! – usr2564301

+3

Jeśli są Państwo zainteresowani tego typu rzeczami, powinniście koniecznie zajrzeć do zestawu instrukcji. – Jester

Odpowiedz

11

To, co obserwujesz, jest artefaktem jednego z rozważań projektowych, które Intel opracował z procesorem 8088. Aby zachować kompatybilność z procesorem 8088, dzisiejsze procesory oparte na procesorach x86 przenoszą niektóre z tych aspektów projektowania, szczególnie w odniesieniu do zestawu instrukcji. W szczególności Intel zdecydował, że 8088 powinien być bardziej wydajny z wykorzystaniem pamięci kosztem wydajności. Stworzyli zestaw instrukcji CISC o zmiennej długości, który zawiera specjalne kodowania ograniczające rozmiar niektórych instrukcji. Różni się to od wielu architektur opartych na architekturze RISC (takich jak starsza Motorola 88000), które używały instrukcji o stałej długości, ale mogły osiągnąć lepszą wydajność.

Kompromitacja pomiędzy szybkością a zestawem instrukcji o zmiennej lub stałej długości wynikała z tego, że procesor potrzebował więcej czasu na dekodowanie instrukcji złożonej długości zmiennej, które są używane do osiągnięcia niektórych mniejszych kodowań instrukcji. Było to prawdziwe w przypadku Intel 8088.

W starszej literaturze (Circa 1980) rozważania na temat lepszego wykorzystania przestrzeni były znacznie bardziej widoczne. Informacje w mojej odpowiedzi dotyczące rejestru AX pochodzą z książki na mojej półce pod tytułem 8088 Assembler Language Programming: The IBM PC, jednak niektóre informacje można znaleźć w artykułach online, takich jak this.

Z artykułu online ta informacja dotyczy sytuacji w AX (akumulator) i innych rejestrach ogólnego przeznaczenia takich jak BX, CX, DX.

AX jest „akumulator«»;

kilka operacji, takich jak: MUL i div wymagają, aby jeden z argumentów jest w akumulatorze niektórych innych operacji, takich jak dodawanie, a SUB może być zastosowany do dowolnego z rejestrów (to znaczy do dowolnego z ośmiu rejestrów ogólnego i specjalnego przeznaczenia), ale jest bardziej wydajny podczas pracy z akumulatorem. ;

jest to jedyny rejestr ogólnego przeznaczenia, który może służyć do pośredniego adresowania. Na przykład instrukcja MOV [BX], AX powoduje, że zawartość AX jest przechowywana w pamięci, której adres jest podany w BX.

CX jest „count '' zarejestrować.

Instrukcje zapętlenie (LOOP, LOOPE i LOOPNE), przesunięcie i obracać instrukcje (RCL, RCR, ROL, ROR, SHL, SHR i SAR), a instrukcje tekstowe (z przedrostkami REP, REPE i REPNE) wykorzystują rejestr zliczania do określenia liczby powtórzeń.

DX jest „dane«»zarejestrować;

jest używany razem z AX słownego wielkości operacji MUL i DIV, a to może również posiadać numer portu i na zewnątrz instrukcje, ale najczęściej jest to dostępne jako wygodne miejsce do przechowywania danych, podobnie jak wszystkich innych rejestrów ogólnego przeznaczenia.

jak widać Intel przeznaczone ogólnego przeznaczenia rejestruje być wykorzystywane do różnych rzeczy, jednak oni też mogą być używane do konkretnych celów i często mają specjalne znaczenie dla instrukcji, z którymi były powiązane. W twoim przypadku zaobserwujesz, że AX jest uważany za Akumulator. Intel wziął to pod uwagę, a dla wielu instrukcji dodano specjalne opkody, aby efektywniej przechowywać kompletne instrukcje. Znalazłeś to z instrukcją MOV (z siekierą, Al), ale także odnosi się do ADC, ADD, AND, CMP, OR, SBB, SUB, TEST, XOR. Każda z tych instrukcji ma krótsze kodowanie opcode, gdy używana z AL, AX, która wymaga jednego bajtu mniej. Alternatywnie możesz kodować AX, AL z dłuższymi opkodami. W twoim przypadku:

00000000 88061234   mov [0x3412],al 
00000004 A21234   mov [0x3412],al 

Są to te same instrukcje, ale z dwoma różnymi kodowaniami.

To jest dobre HTML x86 instruction set reference, który jest dostępny online, jednak Intel zapewnia bardzo szczegółowe instruction reference dla IA-32 (i386 itp.) I 64-bitowych architektur.

+2

Innym krótkim opcode przypadku opcode jest rotate-by-one, zapisując bajt 'imm8' dla' rol/ror/rcl/rcr'. Dzięki szalonym dziwactwu CISC x86, obróć o 1 zestaw "OF" (flaga przepełnienia) zgodnie z danymi, ale obraca się o inne wartości, pozostawiając je niezdefiniowane. Może to dotyczyć tylko krótkiego kodu operacyjnego, a nie "C1 C0 01" (długa forma 'rol eax, 1') Zgodnie z http://agner.org/optimize/ i http://users.atw.hu /instlatx64/GenuineIntel00506E3_Skylake_InstLatX64.txt, Intel IvyBridge, Haswell i Skylake mają podwójną przepustowość dla długiej formy. SandyBridge pobiera 2 upy dla każdej z postaci, nawet 'count! = 1'. –