Какую адресную инструкцию использует процессор x86? - PullRequest
0 голосов
/ 15 ноября 2018

Я узнал об одной адресной, двухадресной и трехадресной инструкции, но теперь я хотел бы знать, какой тип адресной инструкции использует x86?

1 Ответ

0 голосов
/ 15 ноября 2018

x86 - это машина регистра, где не более 1 операнда для любой инструкции может быть явным адресом памяти вместо регистра, используя режим адресации, такой как [rdi + rax*4].(Существуют инструкции, которые могут иметь 2 операнда памяти, причем один или оба являются неявными, однако: Какие инструкции x86 принимают два (или более) операнда памяти? )

Типичное целое число x86инструкции имеют 2 операнда, оба явных, например add eax, edx, что делает eax+=edx.

В устаревшем коде x87 FP используются инструкции с 1 операндом со стеком x87как faddp st1, где вершина стека x87 (st0) является неявным операндом.SSE2 является базовой для x86-64, поэтому он больше не используется.

Современный код FP использует SSE / SSE2 с 2-операндными инструкциями, такими как addsd xmm0,xmm1 или 3-операндными кодировками AVX, такими как vaddsd xmm2, xmm0, xmm1

Существуют инструкции x86 с 0, 1, 2, 3 и даже 4 явными операндами.

Существует несколько форматов команд, но явный reg / memoryоперанды обычно кодируются в байте ModR / M, который следует за байтом (-ами) кода операции.Имеет 3 поля:

  • 2-битный режим для операнда r / m (регистр прямой reg, регистр косвенный [reg], [reg + disp8], [reg+disp32]).Режимы с битами смещения сигнализируют, что эти байты следуют за байтом ModR / M.
  • 3-битное поле r / m (регистр, используемый для этого операнда, или для режимов адресации памяти, код выхода, который означает, что естьмасштабный / индексный / базовый байт после ModRM, который может кодировать режимы адресации с масштабированным индексом для операнда r / m).См. rbp не разрешен в качестве базы SIB? для подробностей особых случаев / escape-кодов.
  • 3-битное поле reg, всегда регистр.

Большинство инструкций доступно как минимум в 2 кодировках: reg / memory destination или reg / memory source.Если вы хотите, чтобы оба операнда были регистрами, вы можете использовать либо код операции, либо add r/m32, r32, либо add r32, r/m32.

В общих инструкциях также есть другие коды операций для форм непосредственного источника, но обычно они используют regполе в ModR / M в качестве дополнительных битов кода операции, поэтому вы все равно получите только 2 операнда, например add eax, 123Исключением является немедленная форма imul с добавлением 286, например, imul eax, [rdi + rbx*4], 12345.Вместо того, чтобы делить пространство кодирования с другими непосредственными инструкциями, он имеет регистр dst и ar / m source в ModR / M плюс непосредственный операнд, подразумеваемый кодом операции.

Некоторые инструкции с одним операндомиспользуйте тот же прием использования поля reg в качестве дополнительных битов кода операции, но без немедленного.например, neg r/m32, not r/m32, inc r/m32 или shl / shr / кодирования поворота, которые сдвигаются на неявную 1 (не на cl или сразу).Так что, к сожалению, вы не можете копировать и сдвигать (до BMI2).

Существуют некоторые специальные кодировки для улучшения плотности кода, такие как однобайтовые кодировки для push rax / push rdx, которые упаковываютreg поле в младшие 3 бита байта кода операции.А в 16/32-битном режиме однобайтовые кодировки для inc / dec любого регистра.Но в 64-битном режиме эти 0x4? коды используются в качестве префиксов REX для расширения полей reg и r/m для предоставления 16 архитектурных регистров.


Есть также инструкции снекоторые или все неявные операнды , например movsb, которые копируют байт из [rsi] в [rdi] и могут использоваться с префиксом rep для повторения этого rcx раз.

Или mul ecx делает edx:eax = eax * ecx.Один явный исходный операнд, один неявный источник и 2 неявных регистра назначения.div / idiv аналогичны.

Инструкции с хотя бы одним явным операндом reg / mem используют для него кодировку ModR / M, но инструкции с нулевыми явными операндами (например, movsb или cdq) не имеют байта ModR / M.У них просто есть код операции.В некоторых инструкциях вообще нет операндов, даже неявных, как mfence.

Непосредственные операнды не могут быть переданы через ModR / M, только самим кодом операции, поэтому push imm32 или push imm8 имеют свои собственные коды операции.Неявные места назначения (память на [rsp] и само RSP обновляются до rsp-=8).


LEA - это обходной путь, который дает x86 с 3 операндами shift-and-add , как lea eax, [rdi + rdi*2 + 123], чтобы сделать eax = rdi*3 + 123 в одной инструкции.См. Использование LEA для значений, которые не являются адресами / указателями? Регистр назначения кодируется в поле reg ModR / M, а два регистра источника кодируются в режиме адресации.(Включая байт SIB, о наличии которого сигнализирует байт ModR / M, используя кодировку, которая в противном случае означала бы base = RSP).


Префиксы VEX (представленные в AVX) обеспечиваютИнструкции с 3 операндами, такие как bzhi eax, [rsi], edx или vaddps ymm0, ymm1, [rsi]. (Для многих инструкций 2-й источник является необязательным, но для некоторых это первый источник.)

3-й операнд закодирован в 2- или 3-байтовом префиксе VEX.


Существует несколько 3-операндных инструкций, не относящихся к VEX, таких как переменные SSE4.1, например vpblendvb xmm1, xmm2/m128, <XMM0> где XMM0 - неявный операнд, использующий этот регистр.

Версия AVX делает его неразрушающим (с отдельным назначением, закодированным в префиксе VEX), и делаетявный операнд управления смешиванием (закодированный в старших 4 битах 1-байтового немедленного). Это дает нам инструкцию с 4 явными операндами, VPBLENDVB xmm1, xmm2, xmm3/m128, xmm4.


x86 довольно дикий и много раз расширялся, но типичный целочисленный код использует в основном 2-операндные инструкции, с хорошим количеством LEA, добавленным, чтобы сохранить инструкции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...