x86 имеет 2 избыточных способа кодирования 2-регистрового экземпляра любой из основных инструкций ALU, которые имеют r / m исходные и r / m целевые формы.
Эта избыточность является следствием того, как машина x86Код позволяет использовать в качестве места назначения память или источник памяти для большинства инструкций: вместо того, чтобы тратить биты в байте ModR / M, чтобы иметь гибкую кодировку для обоих операндов, для большинства инструкций есть просто два отдельных кода операции.
(Вот почему два явных операнда памяти, таких как xor [eax], [ecx]
, запрещены для любой инструкции. Только несколько инструкций, в которых один или оба операнда памяти являются неявными, например, rep movs
или push [mem]
, допускают два операнда памяти, но не одининструкция с двумя отдельными режимами адресации в кодировке ModR / M.)
Для команд reg, reg нет разницы в том, как они декодируются и выполняются на любых известных мне ЦП;единственный раз, когда вам нужно позаботиться о том, какую кодировку использует ваш ассемблер, это когда вы хотите, чтобы машинный код удовлетворял некоторым другим требованиям, например, при использовании только байтов, которые представляют печатные символы ASCII.(например, для эксплойта).
Некоторые ассемблеры имеют синтаксис для переопределения выбора кодировки по умолчанию, например, GAS имеет суффикс .s
для получения кодировки не по умолчанию .Теперь это устарело, и вы должны использовать префиксы {load}
или {store}
перед мнемоникой ( см. Документы ), например:
{load} xor %eax, %ecx
{store} xor %eax, %ecx
{vex3} vpaddd %xmm0, %xmm1, %xmm1
vpaddd %xmm0, %xmm1, %xmm1 # default is to use 2-byte VEX when possible
gcc -c foo.S && objdump -drwC foo.o
0: 31 c1 xor %eax,%ecx
2: 33 c8 xor %eax,%ecx
4: c4 e1 71 fe c8 vpaddd %xmm0,%xmm1,%xmm1
9: c5 f1 fe c8 vpaddd %xmm0,%xmm1,%xmm1
(Связано: Какие методы могут использоваться для эффективного расширения длины инструкций на современном x86? для вариантов использования для {vex3}
, {evex}
и {disp32}
.)
NASM также имеет префиксы {vex2}
, {vex3}
и {evex}
с тем же синтаксисом, что и у GAS: {vex3} vpaddd xmm1, xmm1, xmm0
.Но я не вижу способа переопределить выбор кодов операций op r/m, r
против op r, r/m
.