Что делает инструкция MOVZBL в синтаксисе IA-32 AT&T?

Какая именно инструкция

movzbl  0x01(%eax,%ecx),%eax

делает?

2 ответа

Решение

Синтаксис AT&T разделяет movzx Инструкция Intel мнемоника в разные мнемоники для разных размеров источника (movzb против movzw). В синтаксисе Intel это:

movzx eax, byte ptr [eax+ecx+1]

т.е. загружать байт из памяти в eax+ecx+1 и расширять ноль до полного регистра.

Кстати, большинство инструментов GNU теперь имеют переключатель или опцию конфигурации для предпочтения синтаксиса Intel. (Такие как objdump -Mintel или же gcc -S -masm=intel, хотя последний влияет на синтаксис, используемый при компиляции inline-asm). Я бы порекомендовал изучить это, если вы не делаете сборку AT&T для жизни. См. Также вики-тег x86 для получения дополнительной документации и руководств.

Пример:

mov $0x01234567, %eax
mov $1, %bl
movzbl %bl, %eax
# %eax == 0000 0001

mov $0x01234567, %eax
mov $-1, %bl
movzbl %bl, %eax
# %eax == 0000 00FF

Мнемоника это:

  • MOV
  • Нулевое расширение
  • Байт (8 бит)
  • в длинную (32-битную)

Есть также версии для других размеров:

  • movzbw: Байт (8-разрядный) в Word (16-разрядный)
  • movzwl: От слова (16 бит) до длинного (32 бита)

Как и большинство инструкций GAS, вы можете опустить последний символ размера при работе с регистрами:

movzb %bl, %eax

но я не могу понять, почему мы не можем опустить предыдущую букву, например, следующая ошибка:

movz %bl, %eax

Почему бы просто не вывести его из размера операндов, когда они являются регистрами для mov а Intel синтаксис?

И если вы используете регистры неправильного размера, он не может скомпилировать, например:

movzb %ax, %eax

Пример запускаемого Intel с утверждениями на GitHub.

Другие вопросы по тегам