MASM x86汇编字符串匹配程序故障求助:无法识别源字符串
问题排查与修正
核心问题:参数传递错误
你的Str_find过程通过栈接收源字符串和目标字符串的地址,但main中调用该过程前未将参数压入栈,导致过程中[ebp+8]和[ebp+12]取到的是栈内垃圾值,根本没有指向正确的字符串缓冲区,这是无法匹配的直接原因。
次要问题与优化点
main中残留无效代码enter code here,需删除。- 源字符串长度计算逻辑可以简化,避免指针来回偏移的混淆。
- 未处理源字符串为空的边界情况(可选优化)。
修正后的完整代码
INCLUDE Irvine32.inc ; Include Irvine32 library for input/output functions .data sourceStr BYTE 100 DUP(0) ; Buffer for source string targetStr BYTE 100 DUP(0) ; Buffer for target string promptSource BYTE "Enter source string (the string to search for): ", 0 promptTarget BYTE "Enter target string (the string to search from): ", 0 promptContinue BYTE "Do you want to do another search? y/n (all lower case): ", 0 errorMsg BYTE "Invalid input. Please enter 'y' or 'n'.", 0dh, 0ah, 0 positionMsg BYTE "Source string found at position ", 0 notFoundMsg BYTE "Source string not found.", 0dh, 0ah, 0 continueChar BYTE 0 ; User input for continuation .code main PROC ; Clear the screen call Clrscr ; Prompt the user to enter the source string and read it mov edx, OFFSET promptSource call WriteString mov edx, OFFSET sourceStr mov ecx, SIZEOF sourceStr call ReadString call Crlf ; Prompt the user to enter the target string and read it mov edx, OFFSET promptTarget call WriteString mov edx, OFFSET targetStr mov ecx, SIZEOF targetStr call ReadString call Crlf ; Call the Str_find procedure to search for the source string in the target string push OFFSET targetStr ; 压入目标字符串地址(对应Str_find的[ebp+12]) push OFFSET sourceStr ; 压入源字符串地址(对应Str_find的[ebp+8]) call Str_find ; Check the result of the search and display appropriate message cmp eax, -1 je NotFound mov edx, OFFSET positionMsg call WriteString call WriteDec call Crlf jmp ContinueSearch NotFound: mov edx, OFFSET notFoundMsg call WriteString ContinueSearch: ; Prompt the user if they want to do another search mov edx, OFFSET promptContinue call WriteString call ReadChar mov continueChar, al call Crlf ; Check user input for continuation and handle accordingly cmp al, 'y' je main cmp al, 'n' je ExitProgram mov edx, OFFSET errorMsg call WriteString jmp ContinueSearch ExitProgram: ; Exit the program exit main ENDP ; Str_find procedure ; Searches for the first occurrence of sourceStr in targetStr. ; Returns: EAX = position (0-based) if found, EAX = -1 if not found Str_find PROC push ebp mov ebp, esp push edi push esi push ebx ; Initialize pointers to sourceStr and targetStr mov esi, [ebp+8] ; 源字符串地址 mov edi, [ebp+12] ; 目标字符串地址 mov ebx, edi ; 保存目标字符串起始位置,用于计算最终偏移 ; 计算源字符串长度 mov edx, 0 findLength: cmp BYTE PTR [esi], 0 je lengthDone inc edx inc esi jmp findLength lengthDone: ; 处理源字符串为空的边界情况:直接返回位置0 cmp edx, 0 je found ; 重置源字符串指针到起始位置 mov esi, [ebp+8] ; Search for sourceStr in targetStr searchLoop: mov ecx, edx ; 加载源字符串长度到ECX,作为cmpsb的循环次数 repe cmpsb ; 逐字节比较,直到不匹配或ECX为0 je found ; 如果全部匹配,跳转到found分支 ; 未匹配,移动目标指针到下一个字符,继续搜索 inc ebx mov edi, ebx cmp BYTE PTR [edi], 0 ; 检查目标字符串是否已到末尾 jne searchLoop ; 未到末尾则继续循环 notFound: ; Set EAX to -1 to indicate source string not found mov eax, -1 jmp finish found: ; Calculate the position of the source string in the target string and store it in EAX sub ebx, [ebp+12] ; 用当前起始位置减去目标字符串基地址,得到0-based偏移 mov eax, ebx finish: ; Clean up the stack and return pop ebx pop esi pop edi pop ebp ret 8 ; 清理栈上的两个双字参数(共8字节) Str_find ENDP END main
关键修正说明
- 参数传递:调用
Str_find前先压入目标字符串地址,再压入源字符串地址,与过程中[ebp+12](目标)、[ebp+8](源)的取值逻辑对应。 - 长度计算:改为从源字符串起始位置逐字节计数,逻辑更直观,避免原代码中指针来回偏移的错误风险。
- 边界处理:新增源字符串为空时直接返回位置0的逻辑,完善鲁棒性。
内容的提问来源于stack exchange,提问作者Nicholas
相关产品推荐
相关产品推荐

