2013-02-03 38 views
0

我試圖在NASM中編寫一個簡單的彙編程序,它將打印5次Hello World。但是,在無限循環印刷hello world中執行失敗。我試圖調試代碼,發現ecx沒有正確執行,並且eax顯示了一些其他值。我的代碼如下:無法在NASM中執行循環

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 

你能幫我通過顯示我的缺點。

+0

我不知道太清楚的ASM,但我認爲你可以從http://www.csee.umbc.edu/portal/help/nasm/sample啓動.shtml和http://blog.markloiseau.com/2012/04/hello-world-nasm-linux/ – user1929959

回答

2

根據X86 calling conventions,寄存器EAX,ECX和EDX被保存。您在致電printf之前保存它們,然後再恢復。

你的代碼中還有一段我不明白的東西(add esp, 8環繞在push/pop中)。我在這裏可以不提供任何解釋,但如果您不明白或者,則可能是錯誤的。

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