У x86-64 екскурсії по посібниках Intel я читав
Мабуть, найдивовижніший факт полягає в тому, що така інструкція, як
MOV EAX, EBX
автоматично нулює верхні 32 бітиRAX
регістру.
Документація Intel (3.4.1.1 регістри загального призначення в 64-бітному режимі в посібнику з базової архітектури), цитована в тому ж джерелі, говорить нам:
- 64-бітні операнди генерують 64-розрядний результат у регістрі загального призначення призначення.
- 32-бітні операнди генерують 32-розрядний результат, розширений нулем до 64-розрядного результату в регістрі загального призначення призначення.
- 8-бітні та 16-бітні операнди генерують 8-бітний або 16-розрядний результат. Верхні 56 біт або 48 біт (відповідно) регістра загального призначення призначення не змінюються операцією. Якщо результат 8-бітної або 16-бітної операції призначений для обчислення 64-бітової адреси, явно підпишіть-розгорніть реєстр до повних 64-біт.
У складі x86-32 та x86-64 16-бітні інструкції, такі як
mov ax, bx
не показуйте такої "дивної" поведінки, що верхнє слово eax дорівнює нулю.
Таким чином: яка причина, чому така поведінка була введена? На перший погляд це здається нелогічним (але причина може бути в тому, що я звик до химерності складання x86-32).
r32
операндом призначення нульових високих 32, а не злиттям. Наприклад, деякі монтажники замінити pmovmskb r64, xmm
з pmovmskb r32, xmm
, зберігаючи REX, тому що 64 - бітна версія призначення поводиться однаково. Незважаючи на те, що розділ "Операція" в посібнику перераховує всі 6 комбінацій джерела 32/64 біт і джерело 64/128 / 256b окремо, неявне розширення нуля форми r32 дублює явне розширення нуля форми r64. Мені цікаво щодо впровадження HW ...
xor eax,eax
або xor r8d,r8d
це найкращий спосіб нульового RAX або R8 (збереження префіксу REX для RAX, а 64-бітний XOR навіть не обробляється спеціально на Silvermont). Пов’язано: Як саме виконують часткові регістри Haswell / Skylake? Здається, що AL пише помилковою залежністю від RAX, а АН непослідовна