одна и та же инструкция по сборке x86 отличается между NASM и GAS

код сборки

mov eax, 0x3a14a5
jmp eax

GAS выдает код операции

0xB8, 0xA5, 0x14, 0x3A, 0x00 
0xFF, 0xE0

в то время как NASM производит и код операции

0x66, 0xB8, 0xA5, 0x14, 0x3A, 0x00 
0x66, 0xFF, 0xE0

Итак, вы видите, что NASM добавляет 0x66 перед кодом. В моей программе (о которой я не буду вдаваться в подробности) код операции GAS работает правильно, а код NASM вызывает сбой, указывающий на то, что эти два кода операции не равны. Почему NASM добавляет 0x66 вперед и как от него избавиться?

обновление: директива bits 32 сработала. Спасибо за быстрый ответ, ссылки и пояснения!


person Bob Blogge    schedule 27.06.2013    source источник


Ответы (2)


Поместите директиву bits 32 в начало файла сборки, и NASM должен сгенерировать тот же машинный код, что и GAS для этой инструкции.

Дополнительная информация в руководстве по NASM:

В режиме BITS 32 ... 32-битные инструкции не требуют префиксов, тогда как инструкции, использующие 16-битные данные, нуждаются в 0x66, а те, которые работают с 16-битными адресами, нуждаются в 0x67.

person Michael    schedule 27.06.2013

http://www.posix.nl/linuxassembly/nasmdochtml/nasmdoca.html :

Коды o16 и o32 указывают, что данная форма инструкции должна быть собрана с размером операнда 16 или 32 бита. Другими словами, o16 указывает префикс 66 в состоянии BITS 32, но не генерирует код в состоянии BITS 16; и o32 указывает на префикс 66 в состоянии BITS 16, но ничего не генерирует в состоянии BITS 32

Кодировка инструкции MOV:

MOV reg32, imm32; o32 B8 + r id

Очевидно, вы находитесь в режиме битов 16. Попробуйте добавить к вашему файлу флаг бит, например.

bits 32
person Lennart    schedule 27.06.2013