х86 ЦМП разница инструкция
Вопрос
В чем (нетривиальная) разница между следующими двумя инструкциями x86?
39 /r CMP r/m32,r32 Compare r32 with r/m32
3B /r CMP r32,r/m32 Compare r/m32 with r32
Фон
Я создаю ассемблер Java, который будет использоваться промежуточным языком моего компилятора для создания исполняемых файлов Windows-32.
В настоящее время у меня есть следующий код:
final ModelBase mb = new ModelBase(); // create new memory model
mb.addCode(new Compare(Register.ECX, Register.EAX)); // add code
mb.addCode(new Compare(Register.EAX, Register.ECX)); // add code
final FileOutputStream fos = new FileOutputStream(new File("test.exe"));
mb.writeToFile(fos);
fos.close();
Для вывода корректного исполняемого файла, содержащего две инструкции CMP в текстовом разделе. Исполняемый файл выводится "текст.exe" ничего интересного делать не буду, но не в этом дело. Класс Compare
является оболочкой вокруг инструкции CMP
.
Приведенный выше код производит (проверяя с OllyDbg):
Address Hex dump Command
0040101F |. 3BC8 CMP ECX,EAX
00401021 |. 3BC1 CMP EAX,ECX
Разница тонкая: если я использую байт-код 39
:
Address Hex dump Command
0040101F |. 39C1 CMP ECX,EAX
00401021 |. 39C8 CMP EAX,ECX
Что заставляет меня задуматься об их синонимичности и о том, почему это вообще существует.3 ответа:
Не имеет значения, какой код операции вы используете, если вы сравниваете два регистра. Единственное различие заключается в сравнении регистра с операндом памяти, так как используемый код операции определяет, что из чего будет вычитаться.
Что касается того, почему это существует: формат инструкций x86 использует байт ModR/M для обозначения либо адреса памяти, либо регистра. Каждая инструкция может иметь только одно значение ModR/M, что означает, что она может обращаться только к одному адресу памяти (не включая специальные инструкции, такие как MOVSB). Так это означает, что не может быть общей инструкции
cmp r/m32, r/m32
, и нам нужны два разных OPC-кода:cmp r/m32, r32
иcmp r32, r/m32
. В качестве побочного эффекта это создает некоторую избыточность при сравнении двух регистров.
Этоизбыточность x86 . Таких случаев гораздо больше. Компилятор / ассемблер может свободно использовать любой из допустимых опкодов
Некоторый ассемблер позволяет вам выбрать, какой код операции испускать. Например на газ можно пристроить".s " для использования другой кодировки команд
10 de adcb %bl,%dh 12 f3 adcb.s %bl,%dh