Oto wyjaśnienie problemu z dostępnością rejestrów:
16-bitowe rejestry w 32-bitowym procesie, oraz 32-bitowe rejestry w 16-bitowym procesie kodowane są prefixem 66h
, dodatkowym bajtem umieszczonym przed kodem właściwej instrukcji. Obecność prefiksu 66h oznacza, że instrukcja operuje na „niewłaściwych” rejestrach (niezgodnych z bieżącym trybem pracy procesora), a jego brak że instrukcja dotyczy „właściwych”, domyślnych rejestrów.
instrukcja |
bajty w trybie 16-bit |
bajty w trybie 32-bit |
mov ax,bx |
89 D8 |
66 89 D8 |
mov eax,ebx |
66 89 D8 |
89 D8 |
W trybie 64-bitowym instrukcje na rejestrach 16- i 32-bitowych są kodowane tak samo jak w trybie 32-bitowym.
Dostęp do rejestrów 64-bitowych uzyskuje się poprzez nowy prefix 48h
(właściwie cały zbiór 16 prefiksów, bo niektóre bity kodują dodatkowe informacje)
instrukcja |
bajty w trybie 16-bit |
bajty w trybie 32-bit |
bajty w trybie 64-bit |
mov ax,bx |
89 D8 |
66 89 D8 |
66 89 D8 |
mov eax,ebx |
66 89 D8 |
89 D8 |
89 D8 |
mov rax,rbx |
- |
- |
48 89 D8 |
Dlaczego jednak nie można użyć prefiksu 48h
w trybach 16- i 32-bitowych?
Dlatego że ma on inne znaczenie: koduje instrukcję dec ax
, więc ciąg 48 89 D8
oznaczałby dec ax : mov ax,bx
albo dec eax : mov eax,ebx
zależnie od trybu.
Ponieważ instrukcję dec ax
od zawsze można też zakodować jako dwa bajty FF C8
, postanowiono zrezygnować z jednobajtowego wariantu tej instrukcji, a kodowi 48h
nadać nowe znaczenie. Podobnie z trybu 64-bitowego wyleciał szereg innych nie używanych instrukcji, jak AAA, AAD i in.
W ten sposób, z powodu zmiany znaczenia niektórych opcode'ów, w trybach 16- i 32-bitowych nie ma żadnej możliwości dostania się do 64-bitowych rejestrów ogólnego przeznaczenia.