0

我试图在 NASM 中编写一个简单的汇编程序,它将打印 Hello World 5 次。但是在打印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在循环中被 push/pop 包围)。我不能在这里提供任何解释,但如果你也不明白,那可能是错误的

于 2013-02-03T19:52:12.830 回答
0

Anton(上图)是对的 - 无法解释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 回答