如何用Irvine库实现格式化输出?字符搜索程序BUG修复求助
修复Irvine32汇编程序的格式化输出及功能合规问题
问题概述
需要实现基于Irvine32.inc的汇编程序,完成以下功能:
- 接收用户输入的目标字符串与待搜索字符
- 返回字符的出现次数、首次出现位置、末次出现位置
当前程序存在两个核心问题:
- 错误使用C风格格式化字符串(含
%c、%d占位符),但Irvine32库的WriteString函数不支持占位符解析,导致输出异常 - 未严格遵循作业规范(未实现自定义搜索过程、未用寄存器返回结果)
当前错误代码
INCLUDE Irvine32.inc .data promptStr BYTE "Enter a string: ", 0 promptChar BYTE "Enter a character to search: ", 0 resultMsg BYTE "Character %c appears %d times. First at %d, last at %d", 0 inputStr BYTE 100 DUP(0) searchChar BYTE ? .code main PROC ; 输入字符串 mov edx, OFFSET promptStr call WriteString mov edx, OFFSET inputStr mov ecx, SIZEOF inputStr call ReadString ; 输入搜索字符 mov edx, OFFSET promptChar call WriteString call ReadChar mov searchChar, al call Crlf ; 错误的格式化输出尝试 mov edx, OFFSET resultMsg mov eax, searchChar ; 此处未正确传递参数,且WriteString不解析占位符 call WriteString exit main ENDP END main
错误运行结果
Enter a string: Hello World
Enter a character to search: l
Character %c appears %d times. First at %d, last at %d
修复方案与合规代码
核心修复点
- 自定义搜索过程:实现
SearchChar过程,遍历字符串统计次数、记录首尾位置,用寄存器返回结果ECX:字符出现次数EBX:首次出现索引(从0开始,未找到则设为-1)ESI:末次出现索引(从0开始,未找到则设为-1)
- 替换格式化输出:放弃占位符,改用Irvine32原生输出函数(
WriteChar、WriteDec、WriteString)逐个输出内容 - 边界处理:字符未找到时输出提示信息
修复后完整代码
INCLUDE Irvine32.inc .data promptStr BYTE "Enter a string: ", 0 promptChar BYTE "Enter a character to search: ", 0 msgHeader BYTE "Search results for '", 0 msgAppear BYTE "':", 0Dh, 0Ah, "Appears ", 0 msgTimes BYTE " times.", 0Dh, 0Ah, "First occurrence at index: ", 0 msgLast BYTE 0Dh, 0Ah, "Last occurrence at index: ", 0 msgNotFound BYTE 0Dh, 0Ah, "Character not found in string.", 0 inputStr BYTE 100 DUP(0) searchChar BYTE ? .code main PROC ; 1. 输入目标字符串 mov edx, OFFSET promptStr call WriteString mov edx, OFFSET inputStr mov ecx, SIZEOF inputStr - 1 ; 留1字节存终止符 call ReadString ; 2. 输入待搜索字符 mov edx, OFFSET promptChar call WriteString call ReadChar mov searchChar, al call Crlf ; 3. 调用自定义搜索过程 mov edx, OFFSET inputStr mov al, searchChar call SearchChar ; 4. 输出结果 mov edx, OFFSET msgHeader call WriteString mov al, searchChar call WriteChar mov edx, OFFSET msgAppear call WriteString ; 判断是否找到字符 cmp ecx, 0 je NotFound ; 输出出现次数 mov eax, ecx call WriteDec mov edx, OFFSET msgTimes call WriteString ; 输出首次出现位置 mov eax, ebx ; EBX存首次位置 call WriteDec mov edx, OFFSET msgLast call WriteString ; 输出末次出现位置 mov eax, esi ; ESI存末次位置 call WriteDec jmp EndOutput NotFound: mov edx, OFFSET msgNotFound call WriteString EndOutput: call Crlf exit main ENDP ; 自定义搜索过程SearchChar ; 参数: ; EDX: 指向目标字符串的指针 ; AL: 待搜索的字符 ; 返回值: ; ECX: 字符出现次数 ; EBX: 首次出现索引(未找到则为-1) ; ESI: 末次出现索引(未找到则为-1) SearchChar PROC push edi mov ecx, 0 ; 初始化次数为0 mov ebx, -1 ; 初始化首次位置为-1 mov esi, -1 ; 初始化末次位置为-1 mov edi, 0 ; 初始化索引计数器 SearchLoop: mov cl, [edx + edi] cmp cl, 0 ; 到达字符串终止符则退出循环 je SearchDone cmp cl, al ; 比较当前字符与搜索字符 jne NextChar ; 找到匹配字符,更新统计信息 inc ecx ; 次数+1 cmp ebx, -1 ; 首次位置未设置则更新 je SetFirstPos mov esi, edi ; 更新末次位置 jmp NextChar SetFirstPos: mov ebx, edi mov esi, edi ; 首次出现时,末次位置也设为当前索引 NextChar: inc edi jmp SearchLoop SearchDone: pop edi ret SearchChar ENDP END main
代码说明
SearchChar过程完全自定义,通过遍历字符串完成统计,所有结果通过寄存器返回,符合作业规范- 输出部分拆分所有内容,直接调用Irvine32的输出函数,彻底解决占位符解析问题
- 增加了字符未找到的边界处理,输出友好提示
内容的提问来源于stack exchange,提问作者Teddy Weaver
相关产品推荐
相关产品推荐

