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

如何在MASM32汇编语言中反向打印文档的行?

在MASM32中实现逐行反向打印文档的解决方案

嘿,我看到你想在MASM32汇编里实现逐行反向打印文档的功能,先看看你给出的基础代码框架,我来帮你补全并优化它,让功能正常跑起来!

首先,你的初始代码已经导入了必要的C库函数,接下来需要补充数据段定义、核心逻辑实现这些关键部分。先把你的基础代码放出来:

.386
.model flat, stdcall
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;导入库文件,并声明我们要使用的函数
includelib msvcrt.lib
extern exit: proc
extern fgets:proc
extern fopen:proc
extern fclose:proc
extern printf:proc
extern getc:proc
extern ftell:proc
extern fseek:proc
extern fputs:proc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;声明start符号为公共符号——程序从此处开始执行
public start

接下来是完整的可运行实现代码,我会加上详细注释帮你理解每一步:

.386
.model flat, stdcall
option casemap:none

; 导入必要的C标准库函数
includelib msvcrt.lib
extern exit:proc
extern fopen:proc
extern fclose:proc
extern ftell:proc
extern fseek:proc
extern getc:proc
extern printf:proc
extern strlen:proc
extern memset:proc

; 数据段定义
.data
    filename db "test.txt",0          ; 要读取的目标文件路径
    open_mode db "r",0                ; 只读模式打开文件
    err_msg db "Failed to open file!",0ah,0dh,0
    fmt_str db "%s",0ah,0dh,0         ; 字符串打印格式
    buffer db 256 dup(0)              ; 存储每行内容的缓冲区
    file_handle dd ?                  ; 文件句柄变量

; 代码段定义
.code
start:
    ; 打开目标文件
    push offset open_mode
    push offset filename
    call fopen
    add esp, 8
    mov file_handle, eax
    cmp eax, 0
    je open_fail                      ; 打开失败则跳转到错误处理

    ; 获取文件总字节数
    push file_handle
    call ftell
    add esp, 4
    mov ebx, eax                      ; ebx暂存文件总长度

    ; 定位到文件末尾前一个字节(跳过EOF标记)
    push 2                            ; SEEK_END 定位模式
    push -1
    push file_handle
    call fseek
    add esp, 12

reverse_loop:
    ; 从后向前逐个读取字符
    push file_handle
    call getc
    add esp, 4
    cmp eax, 0ah                      ; 判断是否遇到换行符(行边界)
    je line_found
    cmp ebx, 0                        ; 判断是否到达文件开头
    je line_found

    ; 将字符存入缓冲区(从后往前填充)
    mov [buffer + ebx - 1], al
    dec ebx

    ; 继续向前移动文件指针
    push 1                            ; SEEK_CUR 相对当前位置移动
    push -1
    push file_handle
    call fseek
    add esp, 12
    jmp reverse_loop

line_found:
    ; 处理文件开头的最后一行(无前置换行符的情况)
    cmp ebx, 0
    jne skip_last_char
    mov [buffer], al
    inc ebx

skip_last_char:
    ; 获取当前行的长度,避免空行干扰
    push offset buffer
    call strlen
    add esp, 4
    cmp eax, 0
    je end_program

    ; 打印当前行
    push offset buffer
    push offset fmt_str
    call printf
    add esp, 8

    ; 清空缓冲区,准备存储下一行
    push 0
    push 256
    push offset buffer
    call memset
    add esp, 12

    ; 循环处理上一行,直到文件开头
    cmp ebx, 0
    jne reverse_loop

end_program:
    ; 关闭文件
    push file_handle
    call fclose
    add esp, 4

    ; 正常退出程序
    push 0
    call exit

open_fail:
    ; 打印文件打开失败的错误信息
    push offset err_msg
    push offset fmt_str
    call printf
    add esp, 8

    ; 异常退出
    push 1
    call exit
end start

关键逻辑说明

  • 反向遍历核心:通过ftell获取文件总长度,再用fseek从文件末尾向前移动指针,实现从最后一行开始读取的效果。
  • 行边界识别:向前读取时遇到换行符0ah即判定为一行的结束(反向视角下是行的起始),此时缓冲区已存储该行的完整内容。
  • 缓冲区管理:每次处理完一行后用memset清空缓冲区,避免残留数据影响下一行的读取和打印。

如果你的需求是每行内容本身也要反转(比如原行是hello,打印olleh),可以额外添加一个字符串反转子过程,在打印前调用它处理缓冲区内容。

内容的提问来源于stack exchange,提问作者Alexandru Prodan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:34:32