这条指令具体是做什么的?
movzbl 0x01(%eax,%ecx), %eax
AT&T 语法将movzx
Intel 指令助记符拆分为不同的助记符,用于不同的源大小(movzb
vs. movzw
)。在英特尔语法中,它是:
movzx eax, byte ptr [eax+ecx+1]
即在 eax+ecx+1 处从内存中加载一个字节并零扩展至完整寄存器。
顺便说一句,大多数 GNU 工具现在都有一个开关或配置选项来选择英特尔语法。(例如objdump -Mintel
or gcc -S -masm=intel
,尽管后者会影响编译 inline-asm 时使用的语法)。如果您不以 AT&T 组装为生,我当然会建议您研究一下。另请参阅x86标签 wiki 以获取更多文档和指南。
最小的例子
mov $0x01234567, %eax
mov $1, %bl
movzbl %bl, %eax
/* %eax == 0000 0001 */
mov $0x01234567, %eax
mov $-1, %bl
movzbl %bl, %eax
/* %eax == 0000 00FF */
助记符是:
还有其他尺寸的版本:
movzbw
:字节(8 位)到字(16 位)movzwl
:字(16 位)到长(32 位)像大多数 GAS 指令一样,您可以在处理寄存器时省略最后一个大小字符:
movzb %bl, %eax
但我不明白为什么我们不能省略最后一个字母,例如以下失败:
movz %bl, %eax
当它们是寄存器 as formov
和 Intel 语法时,为什么不直接从操作数的大小中推断出来呢?
如果您使用错误大小的寄存器,则无法编译,例如:
movzb %ax, %eax