使用TASM编写的文件字符对比程序无输出问题求助
问题:TASM汇编程序对比文件无输出内容排查
任务背景
逐字符对比两个文本文件内容,将第一个文件中与第二个文件对应位置不匹配的字符及其在文件中的位置写入新文本文件,使用TASM汇编器实现。
问题现象
编写的程序通过Turbo Assembler编译运行后,output.txt无任何内容。所有文件在同一目录下:
file1.txt内容:abobabiba1file2.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
修正说明
- 显式初始化
ds寄存器,确保large模型下正确访问数据段。 - 优化文件读写流程:打开文件后立即读取并关闭,避免句柄冲突。
- 分两次遍历缓冲区:先收集并写入所有不匹配位置,再写入对应字符,符合预期输出格式。
- 修正文件写入逻辑:使用
ah=40h正确写入文件,避免指针重置和无效内容写入。 - 以字符0作为文件结束标志,确保遍历到实际文件末尾。
内容的提问来源于stack exchange,提问作者ᅠWOlF
相关产品推荐
相关产品推荐

