编写操作系统内核时INT 13h无法读取扇区19的问题求助
编写操作系统内核时INT 13h无法读取扇区19的问题求助
嘿,我来帮你拆解下这个问题:你用INT 13h的02h读扇区功能读取第19个扇区时失败,AH返回的0x01错误码,对应的是无效参数/无法执行的磁盘命令,大概率是你给BIOS的CHS寻址参数设置错了。
先把你的代码贴出来方便分析:
mov ax, #0x3000 mov es, ax mov ax, #0x0201 mov bx, word ptr [bp - 6] ; bx = 0x000, 0x200, 0x400, ... xor ch, ch mov cl, byte ptr [bp - 8] ; cl = target cluster to read xor dx, dx int 0x13 jc load_cluster_carry ; carry == 1 when error xor ax, ax inc ax jmp load_cluster_end load_cluster_carry: xor ax, ax load_cluster_end: mov word ptr [bp - 10], ax
核心问题出在CL寄存器的使用上——你可能误以为CL就是单纯的扇区号,但INT 13h的02h功能里,CL的格式是分两部分的:
- 低6位:扇区号(范围1-63)
- 高2位:柱面号的高两位
同时,CH是柱面号的低8位,DH是磁头号。
假设你的磁盘是常见的1.44MB软盘(每个磁道18个扇区、双面),那第19个扇区根本不在柱面0、磁头0上——它应该是柱面0、磁头1、扇区1。你现在直接把CL设为19,还把DX清零(也就是磁头号DH=0),BIOS会认为你要读一个不存在的扇区,自然返回0x01错误。
给你一个正确计算CHS参数的思路(以每个磁道18扇区为例):
- 先把扇区号转成从0开始的索引:
sector_idx = target_sector - 1(比如19转成18) - 计算所在的磁道号(从0开始):
track = sector_idx / 18(18/18=1) - 计算磁头号:
head = track % 2(1%2=1) - 计算实际柱面号:
cylinder = track / 2(1/2=0) - 计算当前磁道内的扇区号:
sector_in_track = sector_idx % 18 + 1(18%18+1=1) - 组装
CL寄存器:CL = (cylinder << 6) | sector_in_track(0<<6 |1=0x01) - 设置其他寄存器:
CH = cylinder(0),DH = head(1),DL保持驱动器号(0是软盘A)
另外还要注意,你代码里xor dx,dx会把DH(磁头号)也设为0,这也是错误的,得根据计算结果设置DH。
最后再核对INT 13h 02h的参数表,确保每个寄存器都正确:
AH=02h:读扇区功能(你这里AX=0x0201,AH是02h,AL是1,扇区数没错)AL:要读取的扇区数量CH:柱面号低8位CL:扇区号(低6位)+ 柱面号高2位(高2位)DH:磁头号DL:驱动器号(0=软盘A,80h=第一个硬盘)ES:BX:数据缓冲区的物理地址(你这里ES=0x3000,BX是偏移,这部分没问题)
按照这个方法重新设置参数,应该就能成功读取扇区19了。
备注:内容来源于stack exchange,提问作者Nascity
相关产品推荐
相关产品推荐

