I've been playing around with the asm
macro in C to directly call some assembly instructions on OS X Mavericks to get a stack pointer address (from %rsp) and I've found really strange behaviour (at least to me) while trying to assign a return value from the assembler code into the %rax register (the one that should by convention hold the function return value). The C code is very simple:
#include <stdio.h>
unsigned long long get_sp(void) {
asm ("mov %rsp, %rax");
return 0;
}
int main(void) {
printf("0x%llx\n", get_sp());
}
If I compile and run the code, the value from %rax register gets printed(the actual stack pointer), which is strange as I would expect the %rax register to be overwritten by "return 0;"
However if I remove the return 0;
a string "0x0" gets printed which is also strange as I would expect the return value from %rax register to be read and printed.
I've tried to run this code(with the only difference using %esp and %eax registers) also on the Ubuntu Linux also and it actually works as I would expect(using the gcc compiler).
Could this be a bug in the llvm-gcc compiler(Apple LLVM version 5.1)?
//EDIT This is the version without the "return 0;"
otool -tV sp.out
sp.out:
(__TEXT,__text) section
_get_sp:
0000000100000f30 pushq %rbp
0000000100000f31 movq %rsp, %rbp
0000000100000f34 movq %rsp, %rax
0000000100000f37 movq -0x8(%rbp), %rax
0000000100000f3b popq %rbp
0000000100000f3c ret
0000000100000f3d nopl (%rax)
_main:
0000000100000f40 pushq %rbp
0000000100000f41 movq %rsp, %rbp
0000000100000f44 subq $0x10, %rsp
0000000100000f48 callq _get_sp
0000000100000f4d leaq 0x3a(%rip), %rdi ## literal pool for: "0x%llx
"
0000000100000f54 movq %rax, %rsi
0000000100000f57 movb $0x0, %al
0000000100000f59 callq 0x100000f6e ## symbol stub for: _printf
0000000100000f5e movl $0x0, %ecx
0000000100000f63 movl %eax, -0x4(%rbp)
0000000100000f66 movl %ecx, %eax
0000000100000f68 addq $0x10, %rsp
0000000100000f6c popq %rbp
0000000100000f6d ret