The following assembly code gives an error when running as
on OSX 10.9.4, but works successfully on Linux (Debian 7.6). In particular, the movq instruction does
You are correct about the movq
instruction not being able to reference the absolute address. This is in part due to the OS X ABI Mach-O format which uses relocatable addressing for symbols.
A Program that is compiled as a position-independent executable (PIE
) generally cannot reference an absolute virtual address in the same manner as movq $_main, %rax
does. Instead, Global Offset Tables are called upon, which allow position relative code (PC-rel
) and position-independent code (PIC
) to extract global symbols at their current absolute address location. Demonstrated below, GOTPCREL(%rip)
creates an interpretation of lea rdi, _msg
:
PC-rel code referencing it's Global Offset Table:
.globl _main
_main:
movq _main@GOTPCREL(%rip), %rax
sub $8, %rsp
mov $0, %rax
movq _msg@GOTPCREL(%rip), %rdi
call _printf
add $8, %rsp
ret
.cstring
_msg:
.ascii "Hello, world\n"
Mac OS X Mach-O Assembler:
$ as -o test.o test.asm
Apple's version of GCC:
$ gcc -o test.out test.o
Output:
$ ./test.out
Hello, world