You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86汇编循环弹出5次MessageBox出现无限循环该如何修正

问题根因

无限循环由32位Windows平台的函数调用约定导致:Win32 API遵循的约定中,ecx、eax、edx属于调用者保存寄存器,被调用的函数(如MessageBoxA)可直接修改这三个寄存器的存储值,不会主动保留原值。循环计数器存储在ecx中,第一次调用MessageBoxA后,ecx内存储的计数初始值5会被覆盖为其他值,后续的dec ecx和jnz判断逻辑失效,最终出现无限循环。

额外隐藏问题:

  • 字符串定义错误:TEXT dd 'This is a message',0中dd用于定义双字数据,字符串应使用db定义字节序列,此前能正常运行属于巧合
  • ExitProcess调用漏传参:修改后的代码调用ExitProcess前未通过push 0传入退出码,会导致程序退出时出现崩溃

修改方案

有两种常用的修复思路,任选其一即可:

方案1:用被调用者保存寄存器存计数器

ebx、esi、edi属于被调用者保存寄存器,Win32 API执行完后会保证这些寄存器的值和调用前一致,直接把计数器存在这些寄存器里即可:

segment .data 
 TITLE db 'Message',0 
 TEXT db 'This is a message',0 
segment .text 
global  start 
extern MessageBoxA 
extern ExitProcess 
start: 
             mov ebx,5
             loop1:
             push 0 
             push TITLE 
             push TEXT
             push 0 
             call MessageBoxA 
             dec ebx
             jnz loop1
             push 0
             call ExitProcess

方案2:调用API前后手动保存恢复ecx

如果一定要用ecx存计数器,可以在调用API前把ecx压栈,调用完再弹栈恢复原值:

segment .data 
 TITLE db 'Message',0 
 TEXT db 'This is a message',0 
segment .text 
global  start 
extern MessageBoxA 
extern ExitProcess 
start: 
             mov ecx,5
             loop1:
             push ecx
             push 0 
             push TITLE 
             push TEXT
             push 0 
             call MessageBoxA 
             pop ecx
             dec ecx
             jnz loop1
             push 0
             call ExitProcess

内容的提问来源于stack exchange,提问作者l0ner9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 22:15:06