I read this page containing a good list of differences between Intel and AT&T syntax for GAS but it did not cover the case of specifying an address with a displacement only.
Here I've assembled four lines with AT&T syntax:
.text
0000 48C7C008000000 mov $8, %rax
0007 488B042508000000 mov (8), %rax
000f 4889F0 mov %rsi, %rax
0012 488B06 mov (%rsi), %rax
The first two lines are different, as expected. The first moves the immediate value 8 into rax and the second moves the contents of address 8 into rax. But with Intel syntax I get the following odd behavior:
.text
.intel_syntax
0000 48C7C008000000 mov %rax, 8
0007 48C7C008000000 mov %rax, [8]
000e 4889F0 mov %rax, %rsi
0011 488B06 mov %rax, [%rsi]
Here the first and second lines assembled to the same machine code! First I thought the square brackets were wrong, so I added the third and fourth lines to the test, and the square brackets do work for memory addressing at least when registers are involved.
All of the documentation I have read show memory addressing examples with at least a base or index register, and sometimes a scale and displacement, but never a displacement only.
I do have experience with the Intel syntax using the NASM assembler, which does distinguish mov rax, 8
and mov rax, [8]
.
Is this a bug in GAS? Or if not, how do I specify the equivalent of NASM's mov rax, [8]
?
I realize it is probably uncommon to specify a displacement-only address but I would like to get a complete understanding of all of the memory addressing forms with this syntax.
48 8b 04 25 08 00 00
for me. – Kasselmov %rax, 8
(which initializesrax
with the constant 8, same as AT&Tmov $8, %rax
). All the addressing operations, as present, use the correct opcodes. – Voyeur