为什么“ push”会在此处引起段错误?

问题描述

我正在为几个月前写的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 (将#修改为@)