Есть ли размер операнда по умолчанию в архитектуре x86-64 (AMD64)?

Это вопрос о префиксах переопределения размера операнда в архитектуре x86-64 (AMD64).

Вот набор инструкций ассемблера (nasm) и их кодировки; под новым я имею в виду регистры r8, …, r15:

67: address-size override prefix | | 4x: operand-size override prefix | | ; Assembler ; | Dst operand | Src operand | — — mov eax,ecx ; | 32-bit | 32-bit | 89 C8 | mov r8d,ecx ; | 32-bit new | 32-bit | 41 89 C8 | mov eax,r9d ; | 32-bit | 32-bit new | 44 89 C8 | mov r8d,r9d ; | 32-bit new | 32-bit new | 45 89 C8 | mov rax,rcx ; | 64-bit | 64-bit | 48 89 C8 | mov r8,rcx ; | 64-bit new | 64-bit | 49 89 C8 | mov rax,r9 ; | 64-bit | 64-bit new | 4C 89 C8 | mov r8,r9 ; | 64-bit new | 64-bit new | 4D 89 C8 | lea eax,[ecx] ; | 32-bit | 32-bit | 67 8D 01 | lea r8d,[ecx] ; | 32-bit new | 32-bit | 67 44 8D 01 | lea eax,[r9d] ; | 32-bit | 32-bit new | 67 41 8D 01 | lea r8d,[r9d] ; | 32-bit new | 32-bit new | 67 45 8D 01 | lea rax,[rcx] ; | 64-bit | 64-bit | 48 8D 01 | lea r8,[rcx] ; | 64-bit new | 64-bit | 4C 8D 01 | lea rax,[r9] ; | 64-bit | 64-bit new | 49 8D 01 | lea r8,[r9] ; | 64-bit new | 64-bit new | 4D 8D 01 | push rax ; | | 64-bit | 50 | push r8 ; | | 64-bit new | 41 50 |

Изучая эти и те же инструкции с другими регистрами, я пришел к следующему. Между «старым» и «новым» регистрами существует пара. Не исчерпывающе:

AX <—> R8 CX <—> R9 DX <—> R10 BX <—> R11 BP <—> R13

Игнорируя префикс размера, байты инструкции относятся не к конкретным регистрам, а к парам регистров. В качестве примера: байты 89 C8 указывают команду mov из источника, который является либо ecx, rcx, r9d, либо r9, в пункт назначения, который является либо eax, rax, r8d, либо r8. Учитывая, что операнды должны быть 32- или 64-битными, существует восемь допустимых комбинаций. Префикс переопределения размера операнда (или его отсутствие) указывает, какая из этих комбинаций является предполагаемой. Например, если префикс присутствует и равен 44, то исходный операнд должен быть 32-битным новым регистром (в этом примере затем сворачиваться до r9d), а местом назначения должен быть 32-битный старый регистр (здесь тогда сигнализация eax).

Возможно, я не совсем правильно понял, но я думаю, что уловил суть. Тогда может показаться, что префиксы переопределения размера операнда переопределяют тот факт, что без них инструкция использовала бы 32-битные «старые» операнды.

Но наверняка есть кое-что, что ускользнет от меня, иначе: какой смысл тогда говорить о «версии x86-64 с размером операнда по умолчанию 64-бит» (например, здесь)?

Или есть способ, работающий на 64-битной машине, установить размер операнда по умолчанию на 32 или 64, и если это так, и если моя программа настроит машину соответствующим образом, я бы увидел разные кодировки?

Также: когда будет использоваться префикс переопределения размера операнда 66H?

Взгляните на руководства Intel по разработке программного обеспечения. Объясняется кодировка и значение префиксов. Я могу написать настоящий ответ позже.   —  person user1752563    schedule 07.07.2021

Префиксы от 40h до 4Fh называются префиксами REX. Они могут указывать 64-битный размер операнда. Они также могут указывать на использование одного из 8 верхних регистров для источника или назначения. Я считаю, что возможна любая комбинация этих вариантов.   —  person user1752563    schedule 07.07.2021

Префикс 66 изменяет размер операнда на 16 бит.   —  person user1752563    schedule 07.07.2021

См., Например, wiki.osdev.org/X86-64_Instruction_Encoding#Encoding бит REX смыслы.   —  person user1752563    schedule 07.07.2021

Да, в машинном коде по умолчанию используется 32-битная версия для большинства инструкций, 64-битная для стека и инструкций перехода / вызова. В источнике сборки нет значения по умолчанию, это должно подразумеваться регистром или указываться явно. (За исключением некоторых ассемблеров, имеющих значение по умолчанию для push / pop.) Обратите внимание, что 16-битный AX соответствует 16-битному R8W, а RAX и R8 — это пара, различающаяся префиксом REX.   —  person user1752563    schedule 07.07.2021

@ecm В частности, префикс REX кодирует четыре бита состояния (один бит для размера операнда, три бита для старших регистров). Простое присутствие префикса REX дополнительно кодирует то, что вы хотите sil, dil, spl и bpl вместо ah, ch, dh и bh.   —  person user1752563    schedule 07.07.2021

@Peter Cordes Под «AX ‹—› R8» я имел в виду, что регистры, которые объединены в пары для целей кодирования, — это eax, rax с одной стороны и r8d, r8 с другой. Но Питер, на вопрос, который я связал, почему вы говорите о «версии x86-64 с размером операнда по умолчанию 64-бит»?   —  person user1752563    schedule 07.07.2021

Версия x86-64 с размером операнда по умолчанию 64-бит является чисто гипотетической. Питер говорит о том, как бы все работало, если бы был процессор, который вел бы такое поведение. Но в реальной жизни это не так.   —  person user1752563    schedule 08.07.2021

Источник: ledsshop.ru

Стиль жизни - Здоровье!