使用x86 nasm函数的Segfaults

时间:2012-11-21 23:12:48

标签: assembly segmentation-fault nasm calling-convention

我正在编写一个带有bison的编译器,并试图实现程序。我找到了"全球intpow"在线示例,并且完全正常,并且我在其后建模我自己的过程调用。功能" bar"在此代码段中只接受一个整数参数,并将其打印出来。当我编译的程序运行并执行时:

-intpow将正常运行,正常程序终止,一个函数声明" bar"将运行为它应该,正常功能终止,但如果我调用bar(并因此添加被评论的三条线,对条形码调用是唯一的),程序将完全按照它应该运行直到非常结束时,它会出现Segmentation Fault。

gdb说这是在 __ bar_end 的最后一个pop ebp ...为什么这个segfaulting?

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

1 个答案:

答案 0 :(得分:2)

问题是sub esp, -4。它向上移动堆栈指针(减去负数正在添加)。并不是说你需要分配任何空间,因为你没有使用它。现在去清理其余的混乱;)