我曾尝试在NASM中编写一个简单的汇编程序,它将打印Hello World 5次。但是执行失败了无限循环打印hello世界。我尝试调试代码,发现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
你能否通过展示我的错误来帮助我。
答案 0 :(得分:2)
根据X86 calling conventions,寄存器EAX,ECX和EDX被呼叫者保存。在致电printf
之前保存它们并在之后恢复。
你的代码中还有一个我无法理解的片段(add esp, 8
被push / pop包围,在循环中)。我不能在这里提供任何解释,但如果您不理解它 ,那可能是错误的。
答案 1 :(得分: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