Windows 10 64位环境下NASM嵌套循环执行异常问题求助
问题分析与修复
嘿,我一眼就看出你嵌套循环的问题出在栈管理失衡上!让我给你拆解清楚:
在你的_draw函数里,每次进入外层循环L1时,你会push dword [h]把内层循环计数器压入栈,但内层循环结束后,你完全没把这个计数器从栈里弹出来。这就导致栈里堆积了已经减到0的旧计数器值——当第二次进入L1时,新的h值会被压到栈的更深位置(ebp-12),但你的代码还在傻乎乎地用ebp-8访问计数器,而这个位置早就变成0了!
所以第一次外层循环正常跑3次,第二次外层循环时内层计数器一开始就是0,只执行1次,第三次同样只执行1次,加起来就是3+1+1=5次,正好和你看到的输出一致。
下面给你两种修复方案,推荐第一种,更简洁高效:
方案1:用寄存器做循环计数器(推荐)
寄存器操作比栈操作更高效,还能彻底避开栈管理的坑:
_draw: push ebp mov ebp, esp ; 外层循环:用ecx保存w的初始值,循环w次 mov ecx, [w] L1: ; 内层循环:用edx保存h的初始值,循环h次 mov edx, [h] L2: push text push x call _print dec edx jnz L2 ; edx不为0就继续内层循环 dec ecx jnz L1 ; ecx不为0就继续外层循环 mov esp, ebp pop ebp ret
方案2:修复栈管理问题
如果你坚持要用栈存储计数器,就得确保每次循环后清理栈,保持平衡:
_draw: push ebp mov ebp, esp push dword [w] L1: push dword [h] L2: push text push x call _print ; 此时栈顶就是内层计数器(_print的ret 8已经清理了参数) dec dword [esp] cmp dword [esp], 0 jg L2 pop eax ; 弹出内层计数器,清理栈 dec dword [ebp-4] cmp dword [ebp-4], 0 jg L1 pop eax ; 弹出门外层计数器,清理栈 mov esp, ebp pop ebp ret
两种方案都能让你的程序输出9次abc,完美符合3×3的循环预期。
内容的提问来源于stack exchange,提问作者Gigo_G
相关产品推荐
相关产品推荐

