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

NASM Linux x64如何检测EOF并停止向屏幕输出文件内容

问题分析与修复方案

你的代码核心问题有两个:

  1. 错误的EOF判断逻辑:你现在拿缓冲区info的地址和0比较,这完全不对——info是BSS段里的固定地址,永远不会是0,所以循环会无限执行,导致最后一次读取的内容被重复输出。
  2. 未正确指定读写的字节数:sys_read和sys_write都需要通过rdx寄存器传递要操作的字节数,你把这部分代码注释掉了,会导致行为不可预测。

正确的EOF检测方式

Linux的sys_read系统调用(x86下编号3)执行后,eax寄存器会返回实际读取的字节数:

  • 返回值为0:表示已经读到文件末尾(EOF),此时应该终止循环。
  • 返回值为正数:表示成功读取了对应字节数的数据,需要输出这些字节。
  • 返回值为负数:表示读取出错,也应该终止循环。

修复后的代码

section .data
    Nile_2 db '/home/mark/Desktop/mynewfile.txt', 0

section .bss
    fd_in  resd 4        ; 存储文件描述符(x86下用32位足够)
    info   resb 26       ; 用resb分配字节缓冲区,26字节

section .text
    global _start        

_start:
; 打开文件(只读)
    mov eax, 5           ; sys_open的系统调用号(x86)
    mov ebx, Nile_2      ; 文件路径
    mov ecx, 0           ; O_RDONLY 只读权限
    int 0x80             ; 调用内核

    mov [fd_in], eax     ; 保存文件描述符

READ:    
; 从文件读取数据
    mov eax, 3           ; sys_read的系统调用号
    mov ebx, [fd_in]     ; 文件描述符
    mov ecx, info        ; 缓冲区地址
    mov edx, 26          ; 最多读取26字节
    int 0x80             

    cmp eax, 0           ; 检查sys_read的返回值
    jle EXIT_READ        ; 返回值<=0(EOF或错误)则退出循环

; 输出读取到的内容
    mov edx, eax         ; 用实际读取的字节数作为输出长度
    mov eax, 4           ; sys_write的系统调用号
    mov ebx, 1           ; 标准输出的文件描述符
    mov ecx, info        ; 缓冲区地址
    int 0x80             

    jmp READ             ; 继续读取

EXIT_READ:
; 关闭文件
    mov eax, 6           ; sys_close的系统调用号
    mov ebx, [fd_in]
    int 0x80 

; 退出程序
    mov eax, 1           ; sys_exit的系统调用号
    int 0x80             

关键修改点说明

  • 把info的定义从resd 26改成resb 26:resd是分配26个双字(104字节),而你只需要26字节的缓冲区,用resb更准确。
  • 恢复mov edx,26:sys_read必须指定最大读取字节数,否则内核不知道要读多少。
  • 用sys_read的返回值(eax)判断EOF:读取后立即检查eax,等于0就跳出循环。
  • 输出时用实际读取的字节数:把eax的值传给edx,这样最后一次读取不足26字节时,只会输出实际读到的内容,不会带上缓冲区里的旧数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:16:10