x86汇编Print函数添加ret指令后输出异常问题求助
问题:添加
ret指令后打印输出多了一个.字符 我用NASM汇编器和GoLink链接器编写了一个打印单个字符的简单函数,代码如下:
STD_OUTPUT_HANDLE equ -11 NULL equ 0 global Start extern ExitProcess, GetStdHandle, WriteConsoleA section .bss msg resb 1 section .text Start: push 'b' call Print Print: ; Function Start push ebp mov ebp,esp ; accepting the argument mov ebx , [esp + 8] mov [msg],ebx ; eax = handle push STD_OUTPUT_HANDLE call GetStdHandle ; WriteConsoleA System call push NULL push 1 push msg push eax call WriteConsoleA ; Funcion end mov esp, ebp pop ebp ret
遇到的问题:移除ret指令时,输出符合预期的b;但添加ret指令后,输出变为b.。请问这是什么原因?
原因分析
- 程序未主动终止:当
Print函数通过ret返回后,程序回到Start中call Print的下一行,但Start之后没有任何终止程序的代码,CPU会继续执行内存中后续的随机垃圾指令。这些垃圾指令意外触发了额外的字符输出,刚好表现为.。 - 无
ret时的巧合终止:移除ret后,Print执行完pop ebp后,EIP指向的是无有效指令的内存区域,操作系统直接回收进程,因此只输出了预期的b。
修复方案
方案1:主动调用ExitProcess终止程序
在Start的call Print之后,添加退出代码,确保程序执行完打印后正常终止:
Start: push 'b' call Print push NULL ; 传递退出码给ExitProcess call ExitProcess
方案2:修复栈平衡(更规范的写法)
因为Print函数的参数是通过push传递的4字节数据,可修改Print的返回指令为ret 4,让函数自动清理参数栈(符合Windows stdcall调用约定):
; 将Print函数末尾的ret替换为: ret 4
两种方案结合使用,程序就能稳定输出b且无额外字符。
内容的提问来源于stack exchange,提问作者Djebbar Abderrahmene
相关产品推荐
相关产品推荐

