我读了this page,其中包含了针对GAS的英特尔和AT& T语法之间差异的良好列表,但它没有涉及仅指定位移地址的情况。
在这里,我用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中。但是使用Intel语法我会得到以下奇怪的行为:
.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]
的等效物?
我意识到指定一个仅位移地址可能并不常见,但我希望用这种语法完全理解所有内存寻址形式。
答案 0 :(得分:7)
gas
确实存在此类错误 - 请参阅http://sourceware.org/bugzilla/show_bug.cgi?id=10637。
似乎是在binutils 2.21.51中(或可能在之前)修复。
答案 1 :(得分:1)
你在这里看到了一个非常特殊的AT& T语法角落案例。通常,对于地址操作数,您有:
<op> [ src, ] displacement(base,index,scale) [, tgt ]
AT&amp; T语法中地址操作数的任何组成部分都是可选的,因此您可以编写mov (%rax, %rbx), ...
或mov 0(%rax, %rbx, 1), ...
或任何其他此类组合。
在 ()
括号内,您通常可以拥有的唯一数字是比例因子(如果存在)。
但汇编程序也接受(并创建相同的代码):
mov <absolute>, ...
mov (<absolute>), ...
仅当()
内的操作数是简单的数字/绝对地址时才有效,否则汇编程序会抱怨您提供的内容不是有效的比例因子。这种等价是AT&amp; T语法中的特殊情况 - 我不确定为什么它被允许。
但是,在AT&amp; T语法中使用$
始终指定常量,而不是地址操作数,这与裸号在英特尔语法中。
以下说明了等价:
$ cat t.s
mov (8), %rax
mov $8, %rax
mov 8, %rax
.intel_syntax
mov %rax, [ 8 ]
mov %rax, 8
mov %rax, %ds:8
$ objdump -w -d t.o
t.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: 48 8b 04 25 08 00 00 00 mov 0x8,%rax
8: 48 c7 c0 08 00 00 00 mov $0x8,%rax
f: 48 8b 04 25 08 00 00 00 mov 0x8,%rax
17: 48 8b 04 25 08 00 00 00 mov 0x8,%rax
1f: 48 c7 c0 08 00 00 00 mov $0x8,%rax
26: 48 8b 04 25 08 00 00 00 mov 0x8,%rax
$ objdump -w -M intel -d t.o
t.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 :
0: 48 8b 04 25 08 00 00 00 mov rax,ds:0x8
8: 48 c7 c0 08 00 00 00 mov rax,0x8
f: 48 8b 04 25 08 00 00 00 mov rax,ds:0x8
17: 48 8b 04 25 08 00 00 00 mov 0x8,%rax
1f: 48 c7 c0 08 00 00 00 mov rax,0x8
26: 48 8b 04 25 08 00 00 00 mov rax,ds:0x8