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

DOSBox挂载磁盘后如何用int 13h直接读磁盘恢复文件?

在DOSBox挂载目录下恢复删除文件的解决方案

问题描述

我在DOSBox中执行命令mount c c:\users\user\folder挂载本地文件夹,删除其中一个文件后想恢复它。我有该文件的字节掩码,打算直接在DOSBox里读取磁盘数据查找这个掩码,但不知道怎么操作。尝试用int 13h读取时,结果全是512个零字节,请问在挂载的驱动器下该如何获取正确的磁盘号、段号?附上我写的汇编代码:

.model tiny
.code
org 100h

Begin:
  jmp Start

FName db 'myfile.txt',0
Count dw 512
position dw 0

Buf db 512 dup(?)

Start:
  
;-------------------------------------------------
;Read from disk to Buf
  
  push cx
  push dx
  push ds
  
  xor ax, ax
  mov ds, ax
  cld
  
  mov ah, 02h                 ; Function code for reading disk sectors
  mov al, 1                 ; Number of sectors to read
  mov ch, 0                   ; Cylinder number (starting from 0)
  mov cl, 2            ; Sector number (starting from 1)
  mov dh, 0                   ; Head number
  mov dl, 02h                 ; Drive number
  ;xor bx, bx
  ;mov es, bx
  lea bx, Buf             ; Buffer to store the sector data
  int 13h       
  
  
  pop ds
  pop dx
  pop cx
  
  
  
;--------------------------------------------------
;Write Buf to file  
  mov ah, 3ch
  mov cx, 1
  mov dx, offset FName
  int 21h
  
  
  
  mov bx, ax
  mov ah, 42h
  mov al, 0
  mov cx, 0
  mov dx, position
  int 21h
  
  
  
  MOV CX, Count
  MOV DX, offset Buf
  MOV ah, 40h
  int 21h
  
  
  mov ah, 3eh
  int 21h
  
;-----------------------------------------------------

Exit:
  mov ah, 4ch
  xor al, al
  int 21h
  


end Begin

核心问题

DOSBox的mount命令创建的是虚拟逻辑驱动器,它基于宿主系统的文件夹模拟DOS文件系统,并非真实的物理磁盘分区。int 13h是BIOS提供的直接访问物理磁盘的中断,DOSBox会拦截这类请求,对于mount挂载的虚拟驱动器,直接返回空数据(也就是你看到的全零扇区)。

可行解决方案

1. 改用DOS文件系统调用遍历空闲簇

  • 利用DOS的int 21h功能调用操作文件系统:
    • 用功能44h 0Dh获取驱动器参数(包括每簇扇区数、总簇数等)
    • 用功能47h获取当前目录的簇号
    • 遍历磁盘上的空闲簇,读取簇内数据匹配字节掩码
  • 优势:完全兼容DOSBox的虚拟挂载环境,不需要直接操作物理磁盘。

2. 将目标文件夹打包为DOS镜像文件

  • 把c:\users\user\folder打包成.img格式的DOS镜像(可使用dd工具或专门的镜像制作软件)
  • 在DOSBox中用imgmount c path/to/your/image.img挂载该镜像,此时imgmount会将镜像模拟为真实物理磁盘
  • 之后int 13h就能正常读取扇区数据,参数设置与真实磁盘一致

3. 修正int 13h参数(仅适用于真实磁盘挂载)

如果是挂载真实磁盘分区而非文件夹,需确保参数正确:

  • 磁盘号dl:80h对应第一个物理硬盘,81h对应第二个,以此类推;虚拟逻辑盘对应的物理磁盘号可通过int 21h功能08h获取
  • 缓冲区地址:int 13h通过es:bx指定缓冲区,你的代码中注释掉了es的设置,tiny模式下es=cs=ds虽能工作,但建议显式设置es确保正确性
  • 扇区参数:ch(柱面号)、cl(扇区号)、dh(磁头号)必须匹配磁盘的真实分区参数,不能随意填写

修正后的示例代码(针对imgmount挂载的镜像)

以下代码增加了错误检查,适配imgmount挂载的镜像文件:

.model tiny
.code
org 100h

Begin:
  jmp Start

FName db 'sector_dump.txt',0
Count dw 512
position dw 0
ErrMsg db 'Disk read error!$'

Buf db 512 dup(?)

Start:
  
;-------------------------------------------------
;Read from disk to Buf
  push cx
  push dx
  push ds
  push es
  
  ; 显式设置es为程序段(tiny模式下cs=ds=es)
  mov ax, cs
  mov es, ax
  
  mov ah, 02h                 ; int13h功能:读扇区
  mov al, 1                   ; 读取1个扇区
  mov ch, 0                   ; 柱面0
  mov cl, 1                   ; 扇区1(MBR所在扇区)
  mov dh, 0                   ; 磁头0
  mov dl, 80h                 ; 磁盘号:第一个物理硬盘(imgmount镜像对应此值)
  lea bx, Buf                 ; 缓冲区地址es:bx
  int 13h       
  
  ; 检查读取是否成功,CF置位则跳转至错误处理
  jc ReadError               
  
  pop es
  pop ds
  pop dx
  pop cx
  
;--------------------------------------------------
;Write Buf to file  
  mov ah, 3ch
  mov cx, 0                   ; 文件属性:普通文件
  mov dx, offset FName
  int 21h
  jc Exit                     ; 创建文件失败则退出
  
  mov bx, ax
  ; 移动文件指针到开头
  mov ah, 42h
  mov al, 0
  mov cx, 0
  mov dx, position
  int 21h
  
  ; 写入缓冲区数据
  mov cx, Count
  mov dx, offset Buf
  mov ah, 40h
  int 21h
  
  ; 关闭文件
  mov ah, 3eh
  int 21h
  
  jmp Exit

ReadError:
  ; 显示错误信息
  mov ah, 09h
  mov dx, offset ErrMsg
  int 21h

Exit:
  mov ah, 4ch
  xor al, al
  int 21h

end Begin

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 00:44:56