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

求汇编实现文本文件两行交换的示例及代码错误排查

汇编实现文件指定两行交换的解决方案

现有代码的崩溃原因

你的代码存在几个核心问题导致运行崩溃:

  1. 行号计数错误:交换逻辑中读取两行后只递增一次currentLine,后续行号完全混乱,引发越界访问或逻辑错误。
  2. 内存拷贝不严谨:用rep movsb硬拷贝128字节,不管实际行长度,可能覆盖内存中其他有效数据,破坏程序状态。
  3. 未处理文件结束边界:交换分支里的call ReadLine没有检查jc eof,读到文件尾时仍继续操作,触发非法访问。
  4. 交换逻辑重复且错误:两个交换分支逻辑完全一致,没有区分被交换的第一行/第二行,导致顺序颠倒或重复写入。

正确的汇编实现示例(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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:35:10