1

我正在用野牛编写编译器,并尝试实现程序。我在网上找到了“global intpow”示例,它工作得很好,并且我根据它进行了自己的过程调用。此代码片段中的函数“bar”只接受一个整数参数,并打印它。当我编译的程序运行并执行时:

-intpow 将按预期运行,对于正常的程序终止,具有“bar”声明的函数将按预期运行,对于正常的函数终止,但是如果我调用 bar (因此添加三行评论说酒吧调用独有),程序将完全按照预期运行,直到最后,它会出现分段错误。

gdb 说它在__bar_end中的最后一个 pop ebp ......为什么这是段错误?

extern printf
extern scanf
extern pow
SECTION .data
printf_int:
    db "%d", 10, 0
printf_float:
    db "%lf", 10, 0
printf_str:
    db "%s", 10, 0
scan_int:
    db "%d", 0
scan_float:
    db "%lf", 0
esp_tmp:
    dd 0

SECTION .text
global intpow
intpow:
    push    ebp
    mov     ebp,esp
    mov     eax,[ebp+12]
    mov     ebx,[ebp+12]
    mov     ecx,[ebp+8]

loop:
    cmp     ecx,1
    cmp     ecx,1
    jle     finish
    dec     ecx
    imul    eax,ebx
    jmp     loop

finish:
    mov     esp,ebp
    pop     ebp
    ret
global main
main:
    push    ebp
    mov     ebp,esp
    jmp     __bar_END
global __bar
__bar:
    push    ebp
    mov     ebp,esp
    sub     esp,-4
    push    DWORD [ebp + 8]
    push    DWORD printf_int
    mov     [esp_tmp], esp
    add     DWORD [esp_tmp], 8
    call    printf
    mov     esp, DWORD [esp_tmp]
    mov     esp,ebp
    pop     ebp
    ret
__bar_END:
    push    DWORD 12 #Unique to bar call
    call    __bar    #unique to bar call
    add     esp,4    #unique to bar call
    push    DWORD str0
    push    DWORD printf_str
    mov     [esp_tmp], esp
    add     DWORD [esp_tmp],8
    call    printf
    mov     esp, DWORD [esp_tmp]
    mov     esp, ebp
    pop     ebp
    ret

SECTION .data

global_vars:    times 0 db 0

true:   db "true",0
false:  db "false",0
str0:   db "hello world",0
4

1 回答 1

2

问题是sub esp, -4. 它将堆栈指针向上移动(减去负数是加法)。并不是说您根本不需要分配任何空间,因为您没有使用它。现在去清理剩下的烂摊子;)

于 2012-11-22T00:20:21.890 回答