W x86-64 Tour Intel Podręczniki , czytam
Być może najbardziej zaskakującym faktem jest to, że instrukcja taka jak
MOV EAX, EBX
automatycznie zeruje górne 32 bityRAX
rejestru.
Dokumentacja firmy Intel (3.4.1.1 Rejestry ogólnego przeznaczenia w trybie 64-bitowym w ręcznej architekturze podstawowej) cytowana w tym samym źródle mówi nam:
- 64-bitowe operandy generują wynik 64-bitowy w docelowym rejestrze ogólnego przeznaczenia.
- 32-bitowe operandy generują wynik 32-bitowy, rozszerzony przez zero do wyniku 64-bitowego w docelowym rejestrze ogólnego przeznaczenia.
- 8-bitowe i 16-bitowe operandy generują wynik 8-bitowy lub 16-bitowy. Górne 56 bitów lub 48 bitów (odpowiednio) docelowego rejestru ogólnego przeznaczenia nie jest modyfikowanych przez operację. Jeśli wynik operacji 8-bitowej lub 16-bitowej ma na celu obliczenie adresu 64-bitowego, jawnie wpisz znak-rozszerz rejestr do pełnych 64-bitów.
W zestawie x86-32 i x86-64 instrukcje 16-bitowe, takie jak
mov ax, bx
nie pokazuj tego rodzaju „dziwnego” zachowania, gdy górne słowo eax jest zerowane.
A zatem: jaki jest powód, dla którego wprowadzono to zachowanie? Na pierwszy rzut oka wydaje się to nielogiczne (ale powodem może być to, że jestem przyzwyczajony do dziwactw asemblera x86-32).
r32
operandem docelowym zerują wysoki 32, zamiast scalać. Na przykład, niektórzy monterzy zastąpi pmovmskb r64, xmm
z pmovmskb r32, xmm
, oszczędzając REX, ponieważ wersja 64bit przeznaczenia zachowuje się identycznie. Mimo że sekcja Operacja podręcznika zawiera osobno wszystkie 6 kombinacji źródła 32/64-bitowego dest i 64/128 / 256b, niejawne rozszerzenie zerowe postaci r32 powiela jawne rozszerzenie zerowe postaci r64. Jestem ciekawy implementacji HW ...
xor eax,eax
lub xor r8d,r8d
jest najlepszym sposobem na wyzerowanie RAX lub R8 (zapisanie prefiksu REX dla RAX, a 64-bitowy XOR nie jest nawet obsługiwany specjalnie w Silvermont). Powiązane: Jak dokładnie działają częściowe rejestry w Haswell / Skylake? Pisanie AL wydaje się mieć fałszywą zależność od RAX, a AH jest niespójne