Loops 使用eax的Fasm循环不工作

Loops 使用eax的Fasm循环不工作,loops,assembly,x86,fasm,Loops,Assembly,X86,Fasm,我试图在汇编中创建一个for循环,其中EAX寄存器被设置为5,并增加到大于10。每增加一次,它就会输出当前值。当我执行我的程序时,它进入一个无限循环,只输出4。为什么EAX的值为4?为什么寄存器EAX没有按应有的方式增加 include 'include/macro/import32.inc' format PE console entry start section '.text' code readable executable start: mov eax,5 loop1:

我试图在汇编中创建一个for循环,其中
EAX
寄存器被设置为5,并增加到大于10。每增加一次,它就会输出当前值。当我执行我的程序时,它进入一个无限循环,只输出4。为什么
EAX
的值为4?为什么寄存器
EAX
没有按应有的方式增加

include 'include/macro/import32.inc'
format PE console
entry start

section '.text' code readable executable

start:

mov eax,5
loop1:
    inc eax
    push eax
    push msg2
    call [printf]
    cmp eax,10
    jb loop1

call [getchar]
push 0
call [exit]

section '.data' data readable writable
msg2  db "%i",0dh,0ah,0

section 'idata' import data readable
library msvcrt,"msvcrt.dll"
import msvcrt,printf,"printf",getchar,"getchar",exit,"exit"

printf
的输出在
eax
中返回,其中包含打印的字符数:在您的案例中为3(数字、CR和LF)。因为小于10,所以循环,添加1(等于4),打印该值,然后重复

您需要做的是在设置
printf
调用之前存储eax(
push eax
),然后在
printf
返回后恢复它(
pop eax
):

loop1:
    inc  eax
    push eax        ; store eax
    push eax
    push msg2
    call [printf]
    add  esp,8      ; clean the stack from the printf call 
    pop  eax        ; restore eax
    cmp  eax,10
    jb   loop1

或者对循环变量使用另一个寄存器,例如
ebx

在使用printf之前始终保留EAX。printf会破坏您的EAX

inc eax
push eax
...call to printf
pop eax
cmp eax,10

您也没有清理打印参数,因此它们会堆积在堆栈上,您的弹出窗口不会弹出正确的内容。@RaymondChen:我完全隔开了那个参数。谢谢你的提醒。我按照你的建议使用了一个辅助寄存器来保存值,它就像一个符咒。你的例子也很好。@Johnathan:问题可能仍然是你正在使用的寄存器。通常,
ecx
edx
不会被保留,因此如果您正在使用其中的任何一个,您的计数器可能仍然会被损坏。