使用堆栈时,程序集不断出现seg错误

时间:2012-10-14 16:23:45

标签: assembly x86 stack

我正在尝试学习汇编,并且发现在尝试从堆栈中推送/弹出数据时我一直在获得段错误。我已经阅读了一些指南,知道堆栈如何工作以及如何使用堆栈;但不知道为什么我一直收到错误。

有人可以帮忙吗?

segment .data
        myvar: db "hello world", 0xA0, 0
        myvarL: equ $-myvar

segment .text
        global _start

_start:
        push ebp
        mov ebp, esp
        push myvarL
        push myvar
        call _hworld

        mov eax, 1
        mov ebx, 0
        int 0x80

_hworld:
        mov eax, 4
        mov ebx, 1
        mov ecx, [ebp+4]
        mov edx, [ebp+8]
        pop ebp
        int 0x80
        ret

我假设+4是32位,然后+8是64位。我不清楚为什么在我读过的一些指南上做这种方式。我会假设myvar是13个字节?

这是错误:

$ ./pushpop 
Segmentation fault

3 个答案:

答案 0 :(得分:0)

只是一个想法

segment .data
    myvar: db "hello world", 0xA0, 0
    myvarL: equ $-myvar
segment .text
    global _start
_start:
    push ebp
    mov ebp, esp
    push myvarL
    push myvar
    call _hworld
    pop  ebp          // 
 //
    mov eax,1
    mov ebx,0
    int 80h  ; // exit

_hworld:
    mov eax, 4
    mov ebx, 1
    mov ecx, [ebp+4]
    mov edx, [ebp+8]
//  pop ebp               <-- this will pop the return address
    int 0x80
    ret

答案 1 :(得分:0)

_start:
        push ebp
        mov ebp, esp ; ebp points to its old value on the stack
                     ; ebp + 4 points to the return address from _start
                     ; ebp + 8 points to 1st on-stack parameter to _start

        push myvarL ; ebp - 4 points to myvarL on stack
        push myvar ; ebp - 8 points to myvar on stack
        call _hworld

;       are we going to now execute _hworld without a call???
;       vvvv

_hworld:
        mov eax, 4
        mov ebx, 1
        mov ecx, [ebp+4] ; ebp + 4 points to return address from _start
        mov edx, [ebp+8] ; ebp + 8 points to 1st on-stack parameter to _start
;                  ^^^^ why???

顺便说一句,我不确定结肠是否正确:myvarL: equ $-myvar,当然,除非push myvarL原来是push 13

哦,这一行:

        pop ebp

将从_hworld窃取返回地址,因此以下ret将从堆栈中获取myvar作为返回地址并尝试执行myvar作为代码

答案 2 :(得分:0)

我的代码是segfaulting的原因是因为我没有在进入_hworld段时保存esp并且在离开时没有恢复它。

这是新的工作代码:

segment .data
    myvar: db "hello world", 0x0A, 0
    myvarL: equ $-myvar
    myvar2: db "super bad test", 0x0A, 0
    myvar2L: equ $-myvar2

segment .text
    global _start

_start:
    push myvarL ; store myvarL on the stack
    push myvar  ; store myvar on the stack
    call _hworld

    push myvar2L    ; store myvar2L on the stack
    push myvar2 ; store myvar2 on the stack
    call _hworld2

    mov eax, 1
    mov ebx, 0
    int 0x80

_hworld:
    push ebp    ; store the current value of ebp on the stack (hence +8)
    mov ebp, esp    ; store current esp in ebp

    mov eax, 4
    mov ebx, 1
    mov ecx, [ebp+8]    ; +4 is old ebp
    mov edx, [ebp+12]
    int 0x80

    mov esp, ebp    ; restore ebp to esp
    pop ebp     ; restore ebp
    ret

_hworld2:
    push ebp    ; store old ebp on the stack
    mov ebp, esp    ; store esp in ebp

    mov eax, 4
    mov ebx, 1
    mov ecx, [ebp +8]   ; +4 is old ebp
    mov edx, [ebp +12]
    int 0x80

    mov esp, ebp    ; restore ebp to esp
    pop ebp     ; restore ebp
    ret