I'm writing some simple x64 assembly code and am having a bit of trouble understanding some fundamentals about how the stack frames are set up.
.section .data
infmt: .asciz "%d"
outfmt: .asciz "%d\n"
.section .text
.extern scanf
.extern printf
.global main
print_number:
... # Omitted for space purposes.
print_rax:
... # Omitted for space purposes.
main:
subq $16, %rsp
movq %rsp, %rsi
leaq infmt, %rdi
movq $0, %rax
call scanf
movq (%rsp), %rdi
call print_number
addq $16, %rsp
ret
For some reason, when I allocate sixteen bytes (or, really, any multiple of 16), the program segmentation faults. Though, if I allocate any other multiple of 8, e.g., 8, 24, ..., it does not segfault. If I save the base pointer and move the stack pointer over to the base pointer, e.g.,
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movq %rsp, %rsi
leaq infmt, %rdi
movq $0, %rax
call scanf
movq (%rsp), %rdi
call print_number
popq %rbp
addq $16, %rsp
ret
The code does not segfault. I want to allocate exactly 16 bytes because main
will declare two local variables. Allocating more wouldn't necessarily hurt anything, but I want to know what is causing the segfault.