【发布时间】:2012-04-30 04:42:18
【问题描述】:
我阅读了this page,其中包含一个很好的列表,其中列出了英特尔和 AT&T 的 GAS 语法之间的差异,但它没有涵盖仅指定具有位移的地址的情况。
这里我用 AT&T 语法组装了四行代码:
.text
0000 48C7C008000000 mov $8, %rax
0007 488B042508000000 mov (8), %rax
000f 4889F0 mov %rsi, %rax
0012 488B06 mov (%rsi), %rax
正如预期的那样,前两行是不同的。第一个将立即值 8 移动到 rax 中,第二个将地址 8 的内容移动到 rax 中。但使用英特尔语法,我得到以下奇怪的行为:
.text
.intel_syntax
0000 48C7C008000000 mov %rax, 8
0007 48C7C008000000 mov %rax, [8]
000e 4889F0 mov %rax, %rsi
0011 488B06 mov %rax, [%rsi]
这里第一行和第二行汇编成相同的机器码!首先我认为方括号是错误的,所以我在测试中添加了第三和第四行,至少在涉及寄存器时方括号确实可以用于内存寻址。
我读过的所有文档都显示了内存寻址示例,其中至少有一个基址或索引寄存器,有时还有比例和位移,但绝不是只有位移。
我确实有使用 NASM 汇编器的英特尔语法的经验,它确实区分mov rax, 8 和mov rax, [8]。
这是 GAS 中的错误吗?或者如果不是,我如何指定 NASM 的 mov rax, [8] 的等价物?
我意识到指定仅位移地址可能并不常见,但我想全面了解使用此语法的所有内存寻址形式。
【问题讨论】:
-
当我使用 Intel 语法组装您的示例时,我 确实 得到了预期的行为。对我来说,生成的机器代码与您显示的完全相同,除了第二行,对我来说是
48 8b 04 25 08 00 00。 -
如果在上面的 GAS Intel Syntax 示例中,您得到了显示的输出,那么是的,您的版本 GAS 为
mov %rax, 8创建了不正确的代码(初始化rax常数 8,与 AT&Tmov $8, %rax相同)。目前的所有寻址操作都使用正确的操作码。
标签: assembly gnu-assembler intel-syntax