【问题标题】:Failed to execute loop in NASM在 NASM 中执行循环失败
【发布时间】:2013-02-03 19:47:05
【问题描述】:

我尝试在 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

你能帮我指出我的错误吗?

【问题讨论】:

标签: c assembly x86 nasm


【解决方案1】:

根据X86 calling conventions,寄存器 EAX、ECX 和 EDX 是调用方保存的。在调用 printf 之前保存它们,然后再恢复。

您的代码中还有一个我无法理解的片段(add esp, 8 被 push/pop 包围,在一个循环中)。我无法在此提供任何解释,但如果您也不了解,那可能是错误的。

【讨论】:

    【解决方案2】:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      相关资源
      最近更新 更多