Онлайн-ассемблер defuse.ca GAS принимает синтаксис AT&T для movb и movw, но не movl?

Я использую https://defuse.ca/online-x86-assembler.htm#disassembly для сборки инструкций x86 в машинный код. (Примечание редактора: он использует ГАЗ в режиме .intel_syntax noprefix.)


Код ниже выдает Error: no such instruction: `movl $0xdeadbeef,0x08048c5f'

movl $0xdeadbeef,0x08048c5f

Но следующий ассемблерный код работает нормально

movb $0xdeadbeef, 0x08048c5f
movw $0xdeadbeef, 0x08048c5f

person Kumar Vikramjeet    schedule 13.10.2014    source источник
comment
Вы не получаете эту ошибку при выполнении кода; вы можете получить эту ошибку, когда пытаетесь собрать/скомпилировать этот код. Показать больше вашего источника.   -  person Dwayne Towell    schedule 13.10.2014
comment
Похоже, вы используете неправильный ассемблер/компилятор. Предоставьте больше информации.   -  person Dwayne Towell    schedule 13.10.2014
comment
В x86 есть разные инструкции для перемещения байтов, двухбайтов, четырехбайтов и 8-байтов. Вы должны сообщить ассемблеру кое-что, чтобы он знал, какой размер цели и, следовательно, какую инструкцию выбрать. movb для вашего конкретного ассемблера, похоже, указывает на перемещение байта, аналогично для movw. mov явно ничего не значит для вашего конкретного ассемблера. ПРОЧИТАЙТЕ РУКОВОДСТВО ПО АССЕМБЛЕРУ, ПРЕЖДЕ ЧЕМ ЗАДАВАТЬ ДОПОЛНИТЕЛЬНЫЕ ВОПРОСЫ ПО ЭТОЙ КОНКРЕТНОЙ ТЕМЕ.   -  person Ira Baxter    schedule 13.10.2014
comment
Руководство по ассемблеру читали?   -  person johnfound    schedule 13.10.2014


Ответы (2)


Кажется, вы используете синтаксис AT&T для своего movl, но на странице, на которую вы ссылаетесь, указано, что ей нужен синтаксис Intel.

Если я правильно понимаю ваше намерение, правильный синтаксис для инструкции, которую вы хотите, будет:

MOV DWORD PTR ds:0x08048c5f, 0xdeadbeef

(который хранит значение двойного слова 0xdeadbeef по адресу 0x08048c5f)

person Joachim Isaksson    schedule 13.10.2014
comment
defuse.ca/online-x86-assembler.htm#disassembly очень странный . Он принимает синтаксис AT&T для movb и movw, но не movl. - person Peter Cordes; 10.04.2019

Это не просто https://defuse.ca/online-x86-assembler.htm вот так странно: он просто использует ГАЗ в режиме .intel_syntax noprefix.

(Итак, вы хотите mov dword ptr [0x08048c5f], 0xdeadbeef, как говорит @Joachim)


Но самое интересное здесь то, что ассемблер GNU принимает movb и movw, но не movl в режиме синтаксиса Intel!!

Однако он не интерпретирует их как синтаксис AT&T. В синтаксисе Intel пункт назначения находится слева, а $0xdeadbeef – допустимое имя символа, поскольку оно начинается с $, а не с цифры. Режим .intel_syntax GAS похож на MASM, где (как и в синтаксисе AT&T) простое имя символа является операндом в памяти.

Удивительно то, что movb принимается в качестве указания размера операнда в байтах для mov, но как только мы преодолеем это, movb $0xdeadbeef, 0x08048c5f будет эквивалентно mov byte ptr [label], 0x5f.

Обратите внимание, что константа 0x08048c5f (которую вы хотели использовать в качестве адреса назначения) является непосредственным исходным операндом. И это усечено до 8 бит. GAS предупреждает об этом, но онлайн-ассемблер скрывает предупреждения, которые помогли бы вам разобраться в этой странности. :(

.intel_syntax noprefix

movb $0xdeadbeef, 0x08048c5f
movw $0xdeadbeef, 0x08048c5f

На моем рабочем столе Linux с as --version = ассемблер GNU (GNU Binutils) 2.31.1

$ as -32 syntax.s -o syntax.o
as -32 -o syntax.o syntax.s 
syntax.s: Assembler messages:
syntax.s:3: Warning: 134515807 shortened to 95
syntax.s:4: Warning: 134515807 shortened to 35935

$ objdump -drwC -Matt syntax.o 

syntax.o:     file format elf32-i386


Disassembly of section .text:

00000000 <.text>:
   0:   c6 05 00 00 00 00 5f    movb   $0x5f,0x0        2: R_386_32     $0xdeadbeef
   7:   66 c7 05 00 00 00 00 5f 8c      movw   $0x8c5f,0x0      a: R_386_32     $0xdeadbeef

$ ld -melf_i386 syntax.o 
ld: warning: cannot find entry symbol _start; defaulting to 0000000008049000
ld: syntax.o:(.text+0x2): undefined reference to `$0xdeadbeef'
ld: syntax.o:(.text+0xa): undefined reference to `$0xdeadbeef'

Пытаясь связать и попросив objdump показать перемещения с -r в .o, дайте понять, что это $0xdeadbeef рассматривается как имя символа, такое же, как если бы я использовал вместо него my_label.

С помощью только онлайн-ассемблера было бы намного сложнее понять это, потому что он показывает вам только машинный код. 00 00 00 00 для адреса назначения — ваш единственный признак того, что произошло что-то странное.


Я понятия не имею, почему принимаются movb и movw, но movl не подразумевает размер операнда двойного слова.

Вероятно, это ошибка GAS, что они вообще принимаются.

person Peter Cordes    schedule 10.04.2019