2

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

有人可以帮忙吗?

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
4

3 回答 3

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
于 2012-10-14T17:00:02.173 回答
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作为代码执行。

于 2012-10-14T17:01:33.207 回答
0

我的代码出现段错误的原因是因为我在进入_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
于 2012-10-14T23:26:09.830 回答