Что делает инструкция 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.