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
相关产品推荐
相关产品推荐

