问题描述
我正在为几个月前写的LISP解释器编写编译器。我当前的方法是生成程序集(nasm),然后使用nasm和gcc进行编译+链接。我在MacOS上。
我目前正在调试一个相当奇怪的段错误。有问题的代码段非常干净(出于调试目的,我缩进以跟踪堆栈):
; Above this point,we do some math and stick the final result into `rax`
; hand written
push rbp
mov rbp,rsp
lea rsi,[0x101]
lea rdi,[rel dbg]
call _printf
mov rsp,rbp
pop rbp
; end hand written
push rax ; push result onto stack
; hand written
push rbp
mov rbp,rsp
lea rsi,[0x102]
lea rdi,[rel dbg]
call _printf
mov rsp,rbp
pop rbp
; end hand written
这行特殊代码在操作之后发生,我们需要保存其结果以供以后调用(因此我们将其放在栈上)。但是我从中得到的输出是:
101
zsh: segmentation fault ./bin
这意味着我以某种方式在这两个printf调用之间进行隔离,其中只有一条指令。我将附加整个源代码(生成并很难阅读,对不起),但是我不会迷惑rsp
,而且我肯定不会用完堆栈空间。
有什么想法吗?
(LISP源代码,在我的怪异方言中-我知道这段代码已损坏,应该永远循环,但甚至还没有达到目的)
(let (REC self n tot) (self self (- n 1) (* n tot)))
(let (fib n) (REC REC n 1))
(fib 5)
我的编译步骤:
nasm my_prog.asm -o my_prog.o -f macho64
gcc my_prog.o -o bin
./bin
(整个源文件)
global _main
extern _printf
extern _fflush
section .text
__init:
ret
_REC:
; START CALL for [rel __local0]
push qword [rel __local0]
push qword [rel __local1]
push qword [rel __local2]
push rbp
mov rbp,rsp
; COmpuTE ARGS for [rel __local0]
mov [rel __local0],rdi
mov [rel __local1],rsi
mov [rel __local2],rdx
; START INLINE for sub
push rcx
; SETUP ARGS for sub (inline)
; MOV ARGS for sub (inline)
mov rax,[rel __local1]
mov rcx,1
; START BODY for sub (inline)
sub rax,rcx
; RESTORE STATE after sub (inline)
pop rcx
; END INLINE for sub
; hand written
push rbp
mov rbp,rbp
pop rbp
; end hand written
; START INLINE for mul
; SETUP ARGS for mul (inline)
; MOV ARGS for mul (inline)
mov rax,[rel __local2]
; hand written
push rbp
mov rbp,[0x10]
lea rdi,rbp
pop rbp
; end hand written
; START BODY for mul (inline)
mul rcx
; RESTORE STATE after mul (inline)
; hand written
push rbp
mov rbp,[rax + 10]
lea rdi,[rel fmt]
call _printf
mov rsp,rbp
pop rbp
; end hand written
; END INLINE for mul
; hand written
push rbp
mov rbp,rsp
mov rsi,rax
lea rdi,rbp
pop rbp
; end hand written
push rax ; push result onto stack
; POSITION ARGS for [rel __local0]
mov rdi,[rel __local0]
pop r10 ; pop result
mov rsi,r10
pop r10 ; pop result
mov rdx,r10
call [rel __local0] ; make the actual call
mov rsp,rbp
pop rbp
pop qword [rel __local2]
pop qword [rel __local1]
pop qword [rel __local0]
; END CALL for [rel __local0]
ret
_fib:
; START CALL for REC
push qword [rel __local0]
push rbp
mov rbp,rsp
; COmpuTE ARGS for REC
mov [rel __local0],rdi
; POSITION ARGS for REC
lea rdi,[rel _REC]
mov rsi,[rel __local0]
mov rdx,1
call _REC ; make the actual call
.__cleanup:
mov rsp,rbp
pop rbp
pop qword [rel __local0]
; END CALL for REC
ret
_main:
; call init
push rbp
mov rbp,rsp
call __init
mov rsp,rbp
pop rbp
; START CALL for printf
push rbp
mov rbp,rsp
; COmpuTE ARGS for printf
; START CALL for fib
push rbp
mov rbp,rsp
; COmpuTE ARGS for fib
; POSITION ARGS for fib
mov rdi,5
call _fib ; make the actual call
mov rsp,rbp
pop rbp
; END CALL for fib
push rax ; push result onto stack
; POSITION ARGS for printf
lea rdi,[rel fmt]
pop r10 ; pop result
mov rsi,r10
call _printf ; make the actual call
mov rsp,rbp
pop rbp
; END CALL for printf
jmp _exit
_exit:
; say bye
push rbp
mov rbp,rsp
mov rdi,0
call _fflush ; flush stdout
mov rsp,rbp
pop rbp
mov rax,0x2000006 ; close
mov rdi,1 ; stdout
syscall
; exit
mov rax,0x2000001 ; exit
mov rdi,0
syscall
section .bss
section .data
__local0: dq 0
__local1: dq 0
__local2: dq 0
__local3: dq 0
__local4: dq 0
__local5: dq 0
fmt: db "%d",10,0
dbg: db "%x",0
__exit_msg: db "Exiting Now...",10
.len equ $ - __exit_msg
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)