0

Hello World を 5 回出力する単純なアセンブリ プログラムを NASM で作成しようとしました。しかし、実行は無限ループで失敗し、hello world を出力します。コードをデバッグしようとしましたecxが、正しく実行されておらずeax、他の値を示していることがわかりました。私のコードは次のとおりです。

    section .data
    msg:    db "Hello World",10,0
    section .text
        global main
        extern printf
    main:   push ebp
        mov ebp,esp

        mov ecx,0
        mov DWORD[esp-4],0x5
        mov eax,DWORD[esp-4]
        jmp .loop
   .loop:
        push eax
        push ecx
        add esp,8

        pop ecx
        pop eax

        cmp ecx,eax
        jne .task

        jmp .done
     .task:
        push DWORD msg
        call printf
        add esp,4

        add ecx,1

        jmp .loop
      .done:
        mov esp,ebp
        pop ebp
        ret

私の過ちを示すことによって私を助けてくれませんか。

4

2 に答える 2

2

X86 の呼び出し規約に従って、レジスタ EAX、ECX、および EDX は呼び出し側で保存されます。呼び出す前にそれらを保存しprintf、後で復元します。

あなたのコードには、私が理解できないフラグメントもあります(add esp, 8ループ内のプッシュ/ポップに囲まれています)。ここでは説明できませんが、あなたも理解していない場合は間違っている可能性があります。

于 2013-02-03T19:52:12.830 に答える
0

アントン(上記)は正しいです-説明のつかないadd esp,8ものはスタックをゴミ箱に捨て、すべてを台無しにします(そしてprintf、あなたが依存しているECXとEAXの値をゴミ箱に捨てると仮定する必要があります)。

参照バージョンは次のとおりです。

section .data
msg:    db "Hello World",10,0
section .text
    global main
    extern printf


main:
    push dword 0x5     ;count = 5;

.next:
    push dword msg
    call printf
    add esp,4

    sub dword [esp],1  ;count--;
    jne .next          ;if(count != 0) goto next;

    add esp,4          ;Remove "count" from stack
    mov eax,0          ;Value to return from "main"
    ret
于 2013-02-03T20:19:02.367 に答える