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

汇编实现文本文件字符串替换:TextManipulations段功能异常排查

汇编字符串替换程序:TextManipulations段修正方案

问题背景

编写汇编程序实现从指定文本文件中搜索目标字符串并替换为指定字符串,输出替换后的文件。现有程序的参数解析、文件打开/创建等前序功能正常,但TextManipulations子程序存在逻辑错误,导致要么替换成功但丢失部分字符,要么功能完全失效。

原程序代码

.MODEL small
.STACK 256
.DATA
    help db "Hello,", 10, 13, "provide arguments like in the example: program.exe data.txt abcd EFG res.txt", 10, 13, "$"
    FileProblem db "Provided file wasn't found.", 10, 13, "Provide arguments like in the example: program.exe data.txt abcd EFG res.txt", 10, 13, "$"
    input db 255 dup(0)
    inputFD dw, ?               
    string1 db 255 dup(0)
    string2 db 255 dup(0)
    output db 255 dup(0)
    outputFD dw, ?              
    buffer db 50000 dup(?)
    tempBuf db 255 dup(?)       
.CODE
Start:
    mov ax, @data
    mov ds, ax

    xor cx, cx
    xor ah, ah
    mov cl, [es:0080h]
    cmp cx, 4
    jbe Helpmsg
    jne SkipHelp

SkipHelp:

    xor di, di
    mov bx, 82h
    mov si, offset input
    call SaveArgument
    mov si, offset string1
    call SaveArgument
    mov si, offset string2
    call SaveArgument
    mov si, offset output
    call SaveArgument

    xor ax, ax
    mov ah, 3Dh
    mov al, 00
    mov dx, offset input
    int 21h
    jc MissingFile
    mov inputFD, ax

    mov ah, 3Fh
    mov bx, inputFD
    mov cx, 200
    mov dx, offset buffer
    int 21h

    mov ah, 3Ch
    mov cx, 0
    mov dx, offset output
    int 21h
    mov outputFD, ax
    
    call TextManipulations
    
    mov ah, 3Eh
    mov bx, outputFD
    int 21h

Final:
    mov ah, 4Ch
    int 21h

Helpmsg:
    mov ah, 09h
    mov dx, offset help
    int 21h
    JMP Final

MissingFile:
    mov ah, 09h
    mov dx, offset FileProblem
    int 21h
    jmp Final


SaveArgument PROC
Begin:
    mov dx, [es:bx]
    inc bx
    cmp dl, 20h
    je StopSpace
    cmp dl, 13
    je StopEnter
    mov byte ptr [si], dl
    inc si
    jmp Begin
StopSpace:
    inc di
    ret
StopEnter:
    cmp di, 3
    jb Helpme
    ret
Helpme:
    mov ah, 09h
    mov dx, offset help
    int 21h
    mov ah, 4Ch
    int 21h
    ret
SaveArgument ENDP


TextManipulations PROC
    mov si, offset buffer
    mov di, offset string1
    xor cx, cx
    push cx

Read:
    mov ah, 3Fh
    mov bx, inputFD
    mov cx, 1
    mov dx, si
    int 21h    

    cmp byte ptr [si], 0
    je Return
    mov al, byte ptr [si]
    mov ah, byte ptr [di]
    cmp al, ah
    je CheckForString
    mov al, 0
    mov ah, 40h
    mov bx, outputFD
    mov dx, offset tempBuf
    mov cx, 1
    int 21h
    mov cx, 1
    mov dx, si
    int 21h
    inc si
    mov di, offset string1
    pop cx
    xor cx, cx
    push cx

    jmp Read

CheckForString:
    pop cx
    inc cx
    inc di
    cmp byte ptr [di], 0
    je PrintString
    push di
    mov di, offset tempBuf
    mov byte ptr [di], al
    pop di
    inc si
    push cx
    jmp Read

PrintString:
    pop cx
    mov ah, 40h
    mov bx, outputFD
    mov cx, 1                           
    mov dx, offset string2
    int 21h
    inc si
    xor cx, cx
    push cx
    jmp Read

Return:
    ret

TextManipulations ENDP


END Start

原TextManipulations段的核心问题

  1. 重复读取文件:主程序已经通过int 21h 3Fh读取了200字节到buffer,但子程序内再次调用3Fh读取,导致文件指针跳转,丢失已读入buffer的数据。
  2. 匹配失败时的临时字符未处理:匹配过程中暂存到tempBuf的字符未在匹配失败时输出,直接丢弃,导致丢失字符。
  3. 替换字符串输出不完整:PrintString中仅输出string2的1个字符,而非整个替换字符串。
  4. 文件结束判断错误:用[si] == 0判断文件结束,但文本文件可能包含空字节,正确的方式是检查int 21h 3Fh的返回值ax是否为0。
  5. 匹配状态重置不完整:匹配失败后,未清空tempBuf中暂存的部分匹配字符,影响后续逻辑。

修正后的TextManipulations段

TextManipulations PROC
    ; 初始化:si指向buffer起始,bp记录已匹配的字符数,di指向tempBuf暂存区
    mov si, offset buffer
    mov bp, 0
    mov di, offset tempBuf

MatchLoop:
    ; 检查buffer是否读完,若读完则尝试读下一批数据
    cmp si, offset buffer + 200
    je RefillBuffer

    mov al, [si]
    mov ah, [string1 + bp]
    cmp ah, 0               ; 判断是否已匹配完整个目标字符串
    je ReplaceString

    cmp al, ah
    je MatchContinue        ; 当前字符匹配,继续匹配下一个
    ; 匹配失败:输出暂存的字符,再输出当前字符,重置匹配状态
    mov cx, bp
    jcxz SkipTempOutput     ; 无暂存字符则跳过
    mov ah, 40h
    mov bx, outputFD
    mov dx, offset tempBuf
    int 21h
SkipTempOutput:
    mov ah, 40h
    mov bx, outputFD
    mov dx, si
    mov cx, 1
    int 21h
    mov bp, 0               ; 重置匹配计数器
    mov di, offset tempBuf  ; 重置暂存区指针
    inc si
    jmp MatchLoop

MatchContinue:
    ; 暂存当前匹配的字符,更新匹配计数器和指针
    mov [di], al
    inc di
    inc bp
    inc si
    jmp MatchLoop

ReplaceString:
    ; 输出替换字符串
    mov cx, 0
    mov di, offset string2
CountReplaceLen:
    inc cx
    cmp [di], 0
    je DoReplace
    inc di
    jmp CountReplaceLen
DoReplace:
    mov ah, 40h
    mov bx, outputFD
    mov dx, offset string2
    int 21h
    mov bp, 0               ; 重置匹配计数器
    mov di, offset tempBuf  ; 重置暂存区指针
    inc si
    jmp MatchLoop

RefillBuffer:
    ; 读取下一批数据到buffer
    mov ah, 3Fh
    mov bx, inputFD
    mov cx, 200
    mov dx, offset buffer
    int 21h
    jcxz EndProcessing      ; ax=0表示文件结束
    mov si, offset buffer   ; 重置si到buffer起始
    jmp MatchLoop

EndProcessing:
    ; 输出剩余的暂存字符
    mov cx, bp
    jcxz Return
    mov ah, 40h
    mov bx, outputFD
    mov dx, offset tempBuf
    int 21h

Return:
    ret
TextManipulations ENDP

修正说明

  1. 移除重复读取:仅在buffer数据读完时才调用3Fh读取下一批,避免文件指针混乱。
  2. 完善匹配逻辑:用bp记录已匹配的字符数,tempBuf暂存匹配过程中的字符,匹配失败时先输出暂存字符再输出当前字符,避免丢数据。
  3. 完整输出替换字符串:先计算string2的长度,再一次性输出整个替换字符串。
  4. 正确判断文件结束:通过int 21h 3Fh的返回值ax判断是否读取到文件末尾。
  5. 重置匹配状态:每次匹配成功或失败后,重置匹配计数器和暂存区指针,确保后续匹配不受影响。

内容的提问来源于stack exchange,提问作者Leonardas SInkevicius

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:29:52