I'm trying to create a trivial console assembly program with arguments. Here's the code:
.section __TEXT,__text
.globl _main
_main:
movl $0, %edi
callq _exit
Here's the compile and link script:
as test.s -o test.o
ld test.o -e _main -o test -lc
Now the program either fails with a segmentation fault, or executes without error, depending on the argument count:
$ ./test
Segmentation fault: 11
$ ./test 1
$ ./test 1 2
$ ./test 1 2 3
Segmentation fault: 11
$ ./test 1 2 3 4
$ ./test 1 2 3 4 5
Segmentation fault: 11
And so on.
Under the LLDB I see a more informative error:
Process 16318 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x00007fffad14b2fa libdyld.dylib`stack_not_16_byte_aligned_error
libdyld.dylib`stack_not_16_byte_aligned_error:
-> 0x7fffad14b2fa <+0>: movdqa %xmm0, (%rsp)
0x7fffad14b2ff <+5>: int3
libdyld.dylib`_dyld_func_lookup:
0x7fffad14b300 <+0>: pushq %rbp
0x7fffad14b301 <+1>: movq %rsp, %rbp
Indeed, if I stop the execution at the first line of the program, I see that the stack is not 16-byte aligned for some argument count, while it is aligned for another. Although the System V ABI for AMD64 states that:
The stack pointer holds the address of the byte with lowest address which is part of the stack. It is guaranteed to be 16-byte aligned at process entry.
What am I missing?