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

コードがセグメンテーション違反を起こした理由は、_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 に答える
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 myvarLpush 13

ああ、そしてこの行:

        pop ebp

から戻りアドレスを盗もうとしている_hworldので、以下は戻りアドレスとしてスタックからretフェッチし、コードとして実行しようとします。myvarmyvar

于 2012-10-14T17:01:33.207 に答える