0

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.

brj
  • 375
  • 2
  • 11

0 Answers0