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
相关产品推荐
相关产品推荐

