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

咨询:旧DOS汇编应用重定向输入完成后切换回键盘输入的方法

修复DOS汇编程序输入重定向后挂起的问题

问题根源

当输入被重定向到文件时,DOS会将标准输入(stdin,句柄0)关联到该文件。文件读取到EOF后,程序若继续调用DOS 21h功能6(DL=0xFF)尝试读取输入,DOS不会自动将stdin切换回键盘——此时功能6会陷入等待(DOS仍认为stdin指向已读完的文件),导致程序挂起。

解决方案

1. 检测输入是否被重定向

在读取输入前,用DOS 21h功能0x44(IOCTL)子功能0x00获取stdin的设备属性,判断是否处于重定向状态:

; 检测stdin是否为重定向(句柄0)
check_redirect:
    mov ah, 0x44
    mov al, 0x00        ; 子功能0:获取设备信息
    mov bx, 0x00        ; stdin句柄
    int 0x21
    jc redirect_error   ; 调用失败,处理错误
    test dl, 0x80       ; 设备属性第7位:1=文件/管道(重定向),0=字符设备(键盘)
    jz input_from_keyboard
    ; 此处为输入重定向状态,执行文件读取逻辑

2. 检测EOF并恢复stdin到键盘

当读取到文件EOF时(不同DOS版本返回值有差异,调试确认:部分版本功能6返回AL=0xFF且CF=0,部分返回CF=1),立即将stdin重新关联到键盘设备(CON):

; 恢复stdin到键盘
restore_stdin:
    ; 打开CON设备(键盘输入)
    mov ah, 0x3D
    mov al, 0x00        ; 只读模式
    lea dx, con_device
    int 0x21
    jc con_open_error   ; 打开CON失败,处理错误
    
    ; 将CON句柄复制到stdin(句柄0)
    mov ah, 0x46
    mov bx, ax          ; 源句柄:CON的句柄
    mov cx, 0x00        ; 目标句柄:stdin
    int 0x21
    jc handle_copy_error
    
    ; 关闭临时CON句柄(可选,DOS会自动管理,但关闭更规范)
    mov ah, 0x3E
    mov bx, ax
    int 0x21
    
    ; 恢复完成,现在stdin指向键盘
    jmp input_from_keyboard

con_device db 'CON', 0   ; 键盘设备名

3. 调整输入读取逻辑

修改功能6的调用逻辑,在重定向状态下检测EOF:

read_input:
    mov ah, 0x06
    mov dl, 0xFF        ; 控制台输入
    int 0x21
    jc no_input         ; 无输入(键盘未按键)
    
    ; 检查是否为EOF(重定向状态下)
    cmp al, 0xFF        ; 适配部分DOS版本的EOF返回值
    je restore_stdin
    
    ; 处理读取到的字符(原有业务逻辑)
    ; ...
    jmp read_input

no_input:
    ; 键盘无输入时的等待/处理逻辑
    ; ...

关键注意事项

  • 不同DOS版本对EOF的返回值有差异,需通过调试确认你的运行环境中EOF的标识。
  • 使用功能0x46复制句柄时,DOS会自动关闭原stdin指向的文件句柄,无需手动操作。
  • 若程序需支持多次重定向,可提前保存原stdin句柄,恢复时切换回去;普通场景直接恢复到CON即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 09:15:35