You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Irvine库实现格式化输出?字符搜索程序BUG修复求助

修复Irvine32汇编程序的格式化输出及功能合规问题

问题概述

需要实现基于Irvine32.inc的汇编程序,完成以下功能:

  • 接收用户输入的目标字符串与待搜索字符
  • 返回字符的出现次数、首次出现位置、末次出现位置

当前程序存在两个核心问题:

  1. 错误使用C风格格式化字符串(含%c、%d占位符),但Irvine32库的WriteString函数不支持占位符解析,导致输出异常
  2. 未严格遵循作业规范(未实现自定义搜索过程、未用寄存器返回结果)

当前错误代码

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


修复方案与合规代码

核心修复点

  1. 自定义搜索过程:实现SearchChar过程,遍历字符串统计次数、记录首尾位置,用寄存器返回结果
    • ECX:字符出现次数
    • EBX:首次出现索引(从0开始,未找到则设为-1)
    • ESI:末次出现索引(从0开始,未找到则设为-1)
  2. 替换格式化输出:放弃占位符,改用Irvine32原生输出函数(WriteChar、WriteDec、WriteString)逐个输出内容
  3. 边界处理:字符未找到时输出提示信息

修复后完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:57:38