46

这条指令具体是做什么的?

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

2 回答 2

49

AT&T 语法将movzxIntel 指令助记符拆分为不同的助记符,用于不同的源大小(movzbvs. movzw)。在英特尔语法中,它是:

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

即在 eax+ecx+1 处从内存中加载一个字节并零扩展至完整寄存器。

顺便说一句,大多数 GNU 工具现在都有一个开关或配置选项来选择英特尔语法。(例如objdump -Mintelor gcc -S -masm=intel,尽管后者会影响编译 inline-asm 时使用的语法)。如果您不以 AT&T 组装为生,我当然会建议您研究一下。另请参阅标签 wiki 以获取更多文档和指南。

于 2012-02-16T19:44:52.967 回答
29

最小的例子

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

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

使用断言在上游运行 GitHub

助记符是:

  • 移动
  • 零扩展
  • 字节(8 位)
  • 长(32 位)

还有其他尺寸的版本:

  • movzbw:字节(8 位)到字(16 位)
  • movzwl:字(16 位)到长(32 位)

像大多数 GAS 指令一样,您可以在处理寄存器时省略最后一个大小字符:

movzb %bl, %eax

但我不明白为什么我们不能省略最后一个字母,例如以下失败:

movz %bl, %eax

当它们是寄存器 as formov和 Intel 语法时,为什么不直接从操作数的大小中推断出来呢?

如果您使用错误大小的寄存器,则无法编译,例如:

movzb %ax, %eax
于 2015-06-29T11:56:32.163 回答