MASM+Irvine32汇编中ret指令未返回主程序问题求助
问题分析
你的MASM汇编代码存在多个关键问题,导致ret指令无法正确返回主程序,反而跳转到过程开头:
标签大小写不匹配:
代码中跳转指令写的是JB Reject(大写R),但实际标签是reject:(小写r)。MASM对标签大小写敏感,这会导致跳转失败,程序执行流混乱,破坏栈结构。reject分支无正确跳转逻辑:
当输入非字母触发reject分支时,执行完提示后没有跳转回循环继续处理下一次输入,代码流会直接走到过程末尾。由于没有正确的返回或跳转指令,程序会错误地跳转到过程开头。存储缓冲区定义错误:
USER_STR BYTE ?仅定义了1个字节的存储空间,输入多个字符时会溢出到后续内存区域,覆盖栈中的返回地址,导致ret指令跳转到错误位置。字母判断逻辑混乱:
原代码对小写字母的判断逻辑错误,会导致小写字母被判定为无效字符触发reject,同时整体判断流程存在逻辑漏洞。
修正后的代码
include Irvine32.inc .data Input_Prompt BYTE "Enter String:", 0 Max_Length_input BYTE "Enter max length to read:", 0 Rejected_mess BYTE "Rejected !", 0 ret_mess BYTE "returning mess !", 0 USER_STR BYTE 256 DUP(?) ; 定义足够大的存储缓冲区 .code main PROC mov edx, offset Max_Length_input ; 提示输入最大长度 call WriteString call Readint mov ecx, eax mov esi, offset USER_STR ; 传递存储缓冲区偏移 call String_Input exit ; 主程序结束需调用exit退出 main endp String_Input PROC mov ebx, 0 mov edx, offset Input_Prompt ; 设置输入提示 l1: call WriteString call Readchar call WriteChar call Crlf ; 判断是否为小写字母 cmp al, 'a' jb check_upper ; 小于'a',检查大写字母 cmp al, 'z' ja reject ; 大于'z',判定为无效 jmp valid_char ; 小写字母,有效 check_upper: ; 判断是否为大写字母 cmp al, 'A' jb reject ; 小于'A',判定为无效 cmp al, 'Z' ja reject ; 大于'Z',判定为无效 valid_char: mov [esi+ebx], al ; 存储有效字符 inc ebx jmp continue_loop ; 跳转到循环收尾处 reject: mov edx, offset Rejected_mess call Crlf call WriteString call Crlf continue_loop: loop l1 ; ECX自动减1,不为0则回到l1循环 mov [esi+ebx], 0 ; 添加字符串结束符,保证WriteString正常输出 mov edx, offset USER_STR ; 显示最终存储的字符串 call WriteString mov edx, offset ret_mess call Crlf call WriteString call Crlf ret ; 正确返回主程序 String_Input endp end main
关键修正说明
- 缓冲区扩容:将
USER_STR改为BYTE 256 DUP(?),避免内存溢出破坏栈中的返回地址。 - 跳转逻辑修复:统一标签大小写,给
reject分支添加跳转回循环的逻辑,确保程序执行流正常。 - 判断逻辑重构:重新梳理字母判断流程,正确识别大小写字母。
- 添加结束符:在有效字符末尾添加
0,保证WriteString能正确终止输出。 - 主程序补全退出指令:添加
exit确保主程序正常结束。
内容的提问来源于stack exchange,提问作者Wakeel Furqan Ahmed
相关产品推荐
相关产品推荐

