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

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

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

делает?

Ответ 1

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

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

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

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

Ответ 2

Пример:

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 бит)
  • to Long (32-разрядный)

Существуют также версии для других размеров:

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

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

movzb %bl, %eax

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

movz %bl, %eax

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

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

movzb %ax, %eax

Runnable Intel пример с утверждениями на GitHub.