I'm working on a hobby compiler project, and am getting frustrated because my generated assembly makes perfect sense to me but causes a segmentation fault on running. For the input printf("%d", strcmp("1", "2"));
, the compiler generates:
.globl _main
_main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
leaq S0(%rip), %rax
movq %rax, %rdi
pushq %rdi
leaq S1(%rip), %rax
movq %rax, %rdi
leaq S2(%rip), %rax
movq %rax, %rsi
callq _strcmp
popq %rdi
movq %rax, %rsi
callq _printf
addq $16, %rsp
popq %rbp
retq
S0:
.asciz "%d"
S1:
.asciz "1"
S2:
.asciz "2"
The compiler starts by generating code to call printf
, since that's what it encounters first. However, the second argument is a function call, so I thought it would be a good idea to push all the arguments I've already parsed, hence the pushq %rdi
(and later popq %rdi
). However, running the program causes a segfault without printing anything, and I'm not sure why. I'm guessing it's either due to stack alignment somehow or it's due to the offset based adressing (leaq S0(%rip), %rax
) not being stored or retrieved correctly. Commenting out the instructions that push and pop %rdi
and after the call to strcmp
re-inserting leaq S0(%rip), %rdi
before callq _printf
causes the program to run as expected.
I've been banging my head against the wall trying to figure this out. If anyone can help figure out exactly what's wrong with the given assembly, it would be much appreciated.
System info: Working on a 2015 Mac running Mac OSX 10.15.6.
$ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin