使用函数 x86 nasm 的隔离错误



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

-intpow 将按预期运行,到正常的程序终止,声明为"bar"的函数将

按其预期运行,到正常的函数终止,但是如果我调用 bar(因此添加注释的三行说 bar 调用唯一),程序将完全按照它应该的方式运行,直到最后, 当它会分段错误。

GDB表示,这是__bar_end年最后的流行音乐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

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

相关内容

  • 没有找到相关文章

最新更新