Assembly 汇编递归过程中的无限循环
在递归过程下添加WriteDec和CRLF调用时,它将进入无限循环Assembly 汇编递归过程中的无限循环,assembly,x86,masm,Assembly,X86,Masm,在递归过程下添加WriteDec和CRLF调用时,它将进入无限循环 我的动机是在右移之后,每次打印eax和crlf的值 当到达0时,似乎有无限个递归调用,因为它一直在打印0 我的印象是,情况不应该如此,因为ZF=1第一次eax=0,因此它跳到跳过结束递归的标签 以下代码在EAX寄存器=0时导致无限循环 .code MAIN PROC mov ecx, 10 L1: push 10 call f1 call exitProcess main ENDP f1 PROC push e
.code
MAIN PROC
mov ecx, 10
L1:
push 10
call f1
call exitProcess
main ENDP
f1 PROC
push ebp
mov ebp, esp
sub esp, 4
mov eax, [ebp+8]
shr eax, 1
call WriteDec
call CRLF
mov [ebp-4], eax
jz skip
call f1
skip:
mov eax, [ebp+8]
call WriteDec
call CRLF
; ** comment out ** mov ebp, [ebp]
mov esp, ebp
pop ebp
ret 4
f1 ENDP
END MAIN
预期结果:
5
2
1
0
1
2
5
10
罪魁祸首在这里:
mov [ebp-4], eax
jz skip
在x86中,MOV指令不设置任何标志,因此JZ将获取上述函数调用遗留的ZF标志的状态
正确的代码如下:
mov [ebp-4], eax
test eax, eax
jz skip
谢谢@hidefromkgb,因为在eax=1之后执行右移时触发了ZF,所以我的印象是,即使是在mov[ebp-4],eax之后,也会执行jz跳过。我只能在将标志设置为0/1的适当命令之后使用标志吗?@Tom.A EFL寄存器的状态保持不变,直到某个标志更改命令将其删除。一般来说,假设您调用的第三方函数保持EFL不变是不安全的,因为里面可能有像ADD或XOR之类的命令。@Tom.A和顺便问一下,您是否绝对确定您调用的函数也不会影响EAX?它会影响EAX,但在添加您的建议或cmp EAX后没有任何问题,0 jz在mov之前跳过command@Tom.A:和hidefrom:否,不覆盖EAX;它没有返回值。Irvine32函数不销毁(关闭)任何寄存器,除非它们的返回值(如果有)。(与标准库调用约定不同,标准库调用约定中EAX、ECX和EDX都是调用阻塞的)。但显然,Irvine32函数被允许对EFLAG进行重击。(该链接指向谷歌的网络缓存,因为普通网站目前已关闭。)