BIOS int 13h/AH=42 无法读取磁盘或写入目标内存位置问题咨询
问题原因与修复方案
首先可以确定:你提到的「二进制未填充、待加载段不满512字节」确实是问题原因之一,同时还有多个其他配置错误共同导致了当前现象。
具体错误点
- 缺失16位代码声明
所有汇编文件开头都没有添加[BITS 16]声明,NASM默认生成的指令编码不符合实模式运行要求,会导致代码执行逻辑异常。 - LBA起始块号配置错误
你在LBA读写包中填写的起始块为dq 0,但引导扇区本身就位于LBA 0的位置,你的.pms段是紧跟在引导扇区之后存储的,正确的起始块应该是dq 1。你当前读入内存的其实是引导扇区本身的内容,自然找不到目标段的代码,int 13h不报错是因为读LBA 0的操作本身是成功的。 - 镜像未对齐扇区
你的.pms段只有几个字节,生成的二进制镜像中.pms段后面没有填充到512字节的整数倍,虚拟机/物理机识别磁盘镜像时,不满一个扇区的内容会被判定为无效,int 13h无法读取这部分内容。 - 跳转地址段不匹配
你当前的jmp pms_s是近跳转,依赖CS寄存器的默认值,而BIOS启动时CS的值并不固定,可能和你LBA读入的段地址(你配置的是0x0)不匹配,导致跳转到错误地址执行。
修复步骤
- 所有汇编文件最顶部添加
[BITS 16]声明,指定生成16位实模式代码。 - 修改LBA包中的起始块配置,将
dq 0改为dq 1。 - 对齐镜像扇区:可以在链接脚本的
.pms段末尾添加. = ALIGN(512);自动对齐,也可以生成二进制文件后用dd if=你的二进制文件 of=disk.img bs=512 conv=sync命令填充到整扇区大小。 - 将跳转指令改为
jmp 0x0:pms_s,强制CS寄存器为0,和LBA读入的段地址保持一致。
内容的提问来源于stack exchange,提问作者JustFast
相关产品推荐
相关产品推荐

