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

使用TASM编写的文件字符对比程序无输出问题求助

问题:TASM汇编程序对比文件无输出内容排查

任务背景

逐字符对比两个文本文件内容,将第一个文件中与第二个文件对应位置不匹配的字符及其在文件中的位置写入新文本文件,使用TASM汇编器实现。

问题现象

编写的程序通过Turbo Assembler编译运行后,output.txt无任何内容。所有文件在同一目录下:

  • file1.txt内容:abobabiba1
  • file2.txt内容:abobapipa1
  • 预期输出:
5 7

bb

原代码

.model large
.stack 1000h
.data
    infile1 db "file1.txt", 0
    infile2 db "file2.txt", 0
    outfile db "output.txt", 0
    buffer1 db 1000h dup(?)
    buffer2 db 1000h dup(?)
    outfile_char db 0
    position db 0
    end_of_file db 0
.code
main proc
    ; 打开第一个输入文件
    mov ah, 3dh
    mov al, 0
    lea dx, infile1
    int 21h
    mov bx, ax ; bx 存储第一个文件描述符

    ; 打开第二个输入文件
    mov ah, 3dh
    mov al, 0
    lea dx, infile2
    int 21h
    mov cx, ax ; cx 存储第二个文件描述符

    ; 创建输出文件
    mov ah, 3ch
    mov al, 0
    lea dx, outfile
    int 21h
    mov dx, ax ; dx 存储输出文件描述符

    ; 将第一个文件内容读取到buffer1
    mov ah, 3fh
    mov bx, ax
    lea dx, buffer1
    mov cx, 1000h
    int 21h
    ; 将第二个文件内容读取到buffer2
    mov ah, 3fh
    mov bx, cx
    lea dx, buffer2
    mov cx, 1000h
    int 21h

    ; 逐字符对比缓冲区内容
    mov si, offset buffer1
    mov di, offset buffer2
    mov cx, 1000h
    mov position, 0
    
loop_start:
    mov al, [si]
    mov bl, [di]
    cmp al, bl
    je skip

    ; 将文件指针设置到文件开头
    mov ah, 42h
    mov al, 0
    mov bx, dx
    int 21h

    ; 向输出文件写入信息
    mov ah, 02h
    mov dl, al
    mov ah, 40h
    mov bx, dx
    mov cx, 1
    mov dx, offset outfile_char
    int 21h
    mov ah, 02h
    mov dl, position
    add dl, '0'
    mov ah, 40h
    mov bx, dx
    mov cx, 1
    mov dx, offset outfile_char
    int 21h
    mov ah, 40h
    mov bx, dx
    mov cx, 1000h
    lea dx, buffer1
    int 21h
    mov ah, 40h
    mov bx, dx
    mov cx, 1000h
    lea dx, buffer2
    int 21h
skip:
    ; 递增位置并移动到下一个字符
    inc si
    inc di
    inc position
    ; 检查是否到达文件末尾
    cmp position, 10h
    jne loop_start

    ; 关闭输出文件
    mov ah, 3eh
    mov bx,dx
    int 21h

    ; 关闭第二个输入文件
    mov ah, 3eh
    mov bx, cx
    int 21h

    ; 关闭第一个输入文件
    mov ah, 3eh
    mov bx, ax
    int 21h

    ; 程序结束
    mov ah, 4ch
    int 21h

main endp
end main  

错误分析

1. 文件读取寄存器混乱

  • 创建输出文件后,dx被赋值为输出文件句柄,但读取第一个文件时错误将bx设为ax(此时ax是输出文件句柄),导致buffer1未正确加载内容。
  • 读取第二个文件时,bx被设为cx(第二个文件句柄),但cx同时被用作读取字节数,寄存器冲突导致buffer2也未正确加载。

2. 输出逻辑完全错误

  • 每次匹配失败时重置输出文件指针到开头,导致写入内容被覆盖。
  • 用ah=02h(屏幕输出指令)后直接调用文件写入,未将待写字符存入outfile_char,实际写入的是初始值0。
  • 错误将整个缓冲区写入输出文件,完全偏离需求。

3. 寄存器使用与文件关闭错误

  • 关闭第一个输入文件时,bx被设为ax(此时ax是关闭第二个文件的返回值,不是第一个文件句柄),句柄无效。
  • large模型未初始化ds寄存器,无法正确访问数据段内容。

4. 循环终止条件不合理

  • 循环终止条件是cmp position, 10h(16),但实际文件内容仅11个字符,多余循环无意义。

修正后的代码

.model large
.stack 1000h
.data
    infile1 db "file1.txt", 0
    infile2 db "file2.txt", 0
    outfile db "output.txt", 0
    buffer1 db 1000h dup(?)
    buffer2 db 1000h dup(?)
    temp_char db 0       ; 临时存储待写入字符
    position db 0
    newline db 0Dh, 0Ah  ; 换行符
    space db ' '         ; 空格
.code
main proc
    mov ax, @data
    mov ds, ax           ; large模型必须显式初始化数据段

    ; 读取file1到buffer1
    mov ah, 3dh
    mov al, 0
    lea dx, infile1
    int 21h
    mov bx, ax
    mov ah, 3fh
    lea dx, buffer1
    mov cx, 1000h
    int 21h
    mov ah, 3eh
    int 21h

    ; 读取file2到buffer2
    mov ah, 3dh
    mov al, 0
    lea dx, infile2
    int 21h
    mov bx, ax
    mov ah, 3fh
    lea dx, buffer2
    mov cx, 1000h
    int 21h
    mov ah, 3eh
    int 21h

    ; 创建输出文件
    mov ah, 3ch
    mov cx, 0
    lea dx, outfile
    int 21h
    mov bx, ax

    ; 第一遍遍历:写入不匹配的位置
    mov si, offset buffer1
    mov di, offset buffer2
    mov position, 0
    
loop_pos:
    mov al, [si]
    mov bl, [di]
    cmp al, 0            ; 检测文件结束
    je end_pos_loop
    cmp bl, 0
    je end_pos_loop
    cmp al, bl
    je skip_pos

    ; 写入位置(从1开始计数)
    mov al, position
    add al, '1'
    mov temp_char, al
    mov ah, 40h
    mov cx, 1
    lea dx, temp_char
    int 21h
    ; 写入空格
    mov ah, 40h
    lea dx, space
    int 21h

skip_pos:
    inc si
    inc di
    inc position
    jmp loop_pos

end_pos_loop:
    ; 写入换行
    mov ah, 40h
    mov cx, 2
    lea dx, newline
    int 21h

    ; 第二遍遍历:写入不匹配的字符
    mov si, offset buffer1
    mov di, offset buffer2
    mov position, 0
    
loop_chars:
    mov al, [si]
    mov bl, [di]
    cmp al, 0
    je end_write
    cmp bl, 0
    je end_write
    cmp al, bl
    je skip_char

    ; 写入不匹配字符
    mov temp_char, al
    mov ah, 40h
    mov cx, 1
    lea dx, temp_char
    int 21h

skip_char:
    inc si
    inc di
    inc position
    jmp loop_chars

end_write:
    ; 关闭输出文件
    mov ah, 3eh
    int 21h

    ; 程序结束
    mov ah, 4ch
    int 21h

main endp
end main  

修正说明

  1. 显式初始化ds寄存器,确保large模型下正确访问数据段。
  2. 优化文件读写流程:打开文件后立即读取并关闭,避免句柄冲突。
  3. 分两次遍历缓冲区:先收集并写入所有不匹配位置,再写入对应字符,符合预期输出格式。
  4. 修正文件写入逻辑:使用ah=40h正确写入文件,避免指针重置和无效内容写入。
  5. 以字符0作为文件结束标志,确保遍历到实际文件末尾。

内容的提问来源于stack exchange,提问作者ᅠWOlF

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:47:02