I'm trying to implement a compiler for a subset of Scheme to x86-64 following this book. For this program
(let ([x (read)])
(let ([y (read)])
(if (if (< x 1) (eq? x 0) (eq? x 2))
(+ y 2)
(+ y 10))))
my compiler generates
start:
callq read_int
movq %rax, %rbx
jmp block34954
.globl main
block34954:
callq read_int
movq %rax, %rcx
jmp block34953
block34953:
cmpq $1, %rbx
jl block34951
jmp block34952
block34951:
cmpq $0, %rbx
je block34949
jmp block34950
block34952:
cmpq $2, %rbx
je block34949
jmp block34950
block34949:
movq %rcx, %rax
addq $2, %rax
jmp conclusion
block34950:
movq %rcx, %rax
addq $10, %rax
jmp conclusion
main:
pushq %rbp
pushq %rbx
movq %rsp, %rbp
subq $16, %rsp
jmp start
conclusion:
addq $16, %rsp
popq %rbx
popq %rbp
retq
where read_int
reads an integer from the standard input and puts it into rax
.
From what I understand, my compiler is assigning rbx
to x
and rcx
to y
and since rbx
is a callee saved register, it also pushes/pops it off the stack in the main
/conclusion
blocks. Furthermore, since stack frames must be 16-byte aligned, it adds/subtracts 16 bytes to account for the pushes/pops in the main
/conclusion
blocks.
However, this program gives me a segfault and running it in gdb says
(gdb) run
Starting program: /<path>/a.out
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e1a3e9 in __vfscanf_internal () from /usr/lib/libc.so.6
which I am unsure what to make of.
I don't understand why this segfaults, any help would be appreciated.
Here is the runtime that has read_int
.