求汇编实现文本文件两行交换的示例及代码错误排查
汇编实现文件指定两行交换的解决方案
现有代码的崩溃原因
你的代码存在几个核心问题导致运行崩溃:
- 行号计数错误:交换逻辑中读取两行后只递增一次
currentLine,后续行号完全混乱,引发越界访问或逻辑错误。 - 内存拷贝不严谨:用
rep movsb硬拷贝128字节,不管实际行长度,可能覆盖内存中其他有效数据,破坏程序状态。 - 未处理文件结束边界:交换分支里的
call ReadLine没有检查jc eof,读到文件尾时仍继续操作,触发非法访问。 - 交换逻辑重复且错误:两个交换分支逻辑完全一致,没有区分被交换的第一行/第二行,导致顺序颠倒或重复写入。
正确的汇编实现示例(DOS环境)
以下是基于DOS中断int 21h的完整实现,支持交换指定两行(示例为第2行和第3行),同时保留其他内容不变:
; 假设已初始化文件句柄:sourceHandle(源文件)、destHandle(目标文件) ; 定义变量 buf db 128 dup(0) ; 存储当前读取的行 tempBuf db 128 dup(0) ; 缓存要交换的第一行 currentLine dw 1 ; 当前行号,从1开始 line1 dw 2 ; 要交换的第一行 line2 dw 3 ; 要交换的第二行 hasCached db 0 ; 是否缓存了第一行 copy_and_swap: call ReadLine ; 读取一行到buf,CF=1表示EOF jc check_cached ; 到文件尾,检查是否有未写入的缓存行 mov ax, currentLine cmp ax, line1 je cache_line ; 是第一目标行,缓存起来 cmp ax, line2 je swap_lines ; 是第二目标行,执行交换写入 ; 普通行,直接写入 call WriteLine inc currentLine jmp copy_and_swap cache_line: ; 缓存当前行到tempBuf,只拷贝有效字符(假设行以0结尾) lea si, buf lea di, tempBuf copy_loop: mov al, [si] mov [di], al inc si inc di cmp al, 0 jne copy_loop mov byte ptr hasCached, 1 inc currentLine jmp copy_and_swap swap_lines: ; 先写入缓存的第一行 lea si, tempBuf call WriteLine ; 再写入当前行 lea si, buf call WriteLine mov byte ptr hasCached, 0 inc currentLine inc currentLine ; 跳过两行的计数 jmp copy_and_swap check_cached: ; 如果还有缓存的行没写(比如line2不存在于文件中) cmp byte ptr hasCached, 1 jne exit lea si, tempBuf call WriteLine exit: ; 关闭文件等清理操作 ret ; -------------------------- ; 辅助函数:从源文件读取一行到buf ; 返回:CF=1表示EOF,buf以0结尾 ReadLine: xor bx, bx read_char: mov ah, 3fh mov bx, sourceHandle mov cx, 1 lea dx, buf[bx] int 21h jc read_eof cmp ax, 0 je read_eof cmp byte ptr buf[bx], 0Dh ; 回车符 je skip_crlf cmp byte ptr buf[bx], 0Ah ; 换行符 je read_done inc bx cmp bx, 127 ; 防止缓冲区溢出 jb read_char read_done: mov byte ptr buf[bx], 0 clc ret skip_crlf: ; 跳过换行符 mov ah, 3fh mov cx, 1 lea dx, buf[bx] int 21h jmp read_done read_eof: stc ret ; -------------------------- ; 辅助函数:将si指向的行写入目标文件 WriteLine: xor cx, cx count_len: cmp byte ptr [si+cx], 0 je write_line inc cx jmp count_len write_line: mov ah, 40h mov bx, destHandle lea dx, si int 21h ; 写入换行符(保持文件格式) mov ah, 40h mov cx, 2 mov dx, crlf int 21h ret crlf db 0Dh, 0Ah
代码关键点说明
- 行缓存逻辑:遇到第一目标行时,只缓存不写入,标记
hasCached,行号正常递增。 - 交换写入逻辑:遇到第二目标行时,先写入缓存的第一行,再写入当前行,行号递增两次(因为处理了两行)。
- 边界处理:文件结束时检查是否有未写入的缓存行(比如指定的第二行不存在),避免数据丢失。
- 安全拷贝:按实际行长度拷贝,而非固定128字节,避免内存破坏。
内容的提问来源于stack exchange,提问作者dodanija
相关产品推荐
相关产品推荐

