C AH=2的BIOS INT 13H每次只能读取72个扇区。为什么?

C AH=2的BIOS INT 13H每次只能读取72个扇区。为什么?,c,operating-system,dos,bios,C,Operating System,Dos,Bios,我正在使用Bochs2.4.5编写引导扇区代码。我使用INT 13H从软盘读取扇区。但是我发现如果扇区计数大于72,INT13将失败。返回码为AH=1。下面是代码,下面是代码。返回代码为AH=1 为什么INT 13H不能读取超过72个扇区 xorb %ah, %ah xorb %dl, %dl int $0x13 # reset the floppy movw $0x8000, %ax movw %ax,%es movw $0, %

我正在使用Bochs2.4.5编写引导扇区代码。我使用INT 13H从软盘读取扇区。但是我发现如果扇区计数大于72,INT13将失败。返回码为AH=1。下面是代码,下面是代码。返回代码为AH=1

为什么INT 13H不能读取超过72个扇区

   xorb %ah, %ah
   xorb %dl, %dl
   int $0x13      # reset the floppy

   movw $0x8000, %ax
   movw %ax,%es        
   movw $0, %bx  # ES:BX is the buffer  
   movb $0x02, %ah
   movb $73, %al # how many sectors to read. 72 is ok, but >=73 is wrong.
   movb $0, %ch
   movb $1, %cl
   movb $0, %dh
   movb $0, %dl

   int $0x13
谢谢你的帮助

更新 按照的说明,我找到了相应的代码。我把它列在这里是为了和我一样困惑的人。完整代码位于


根据,1.44MB软盘上每磁道的扇区数为18。因为18*4=72,这可能是一个线索。BIOS可能不希望一次读取超过一定数量的磁道。

您使用的是Bochs,因此可以在中找到答案:BIOS正在对扇区数执行显式范围检查,如果扇区数大于72(或等于0),则拒绝该检查.

正如所指出的,简单的答案是,这只是Bochs执行的范围检查。这是基于一个2.88Mb软盘多磁道软盘控制器的读取,它将被限制为72个扇区



令人高兴的答案是,由于向后兼容,当前BIOS只支持单面读取,对于1.44Mb软盘,最多可读取18个扇区。这取决于起始扇区,因此实际最大值将达到轨道上剩余的总值。从USB闪存驱动器引导和运行是os-dev过时软盘的简单替代方法。根据引导驱动器标识符(
dl
register),可以使用相同的BIOS磁盘/软盘功能。

感谢提供线索。但是为什么要乘以4呢?我会继续看维基百科,虽然这已经快4年了,但我会做这样的观察。我不认为72是博克斯的武断。72恰好是所生产的最大容量软盘(2.88mb软盘,每条磁道36个扇区,2个磁头)的单个圆筒上的扇区数36*2=72。续。。。此外,并不是所有的生物传感器都支持在圆柱体边界上读取数据,所以您应该假设无法通过它进行编程。因此,在出现的任何软盘格式上,有意义的最大值都是72%,这是我在前面的评论中给出的原因。我不是汇编语言的老手。您能指出范围检查的位置吗?我的答案中的链接应该将您带到正确的位置,即C代码:
bios/rombios.C
的第7211行(从Bochs v2.4.5开始),这实际上是
int13\u diskette\u函数()<代码> >包含范围检查的参数验证是第一个<代码>(如果……)/代码>,在72207221行。我想在这里评论/提问,你不应该考虑每个轨道的扇区吗?也就是说,调用bios中断0x13并在1.44mb软盘上请求超过18个扇区真的有效吗?如果您的引导加载程序正在从一个相邻的集群读取数据,它应该根据需要进行计算以推进任何轨迹/圆柱体。这取决于BIOS和硬件。一个真正的软盘控制器至少应该允许一次读取两个磁头(多磁道模式),并且一个真正的BIOS支持这一点。Bochs BIOS接受多达72个扇区的请求,并向FDC发出单个命令;中行银行效仿FDC。因此,它在Bochs中运行,但如果计划在真实系统上运行,则可能值得更加谨慎。
7220       if ((drive > 1) || (head > 1) || (sector == 0) ||
7221           (num_sectors == 0) || (num_sectors > 72)) {
7222         BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
7223         SET_AH(1);
7224         set_diskette_ret_status(1);
7225         SET_AL(0); // no sectors read
7226         SET_CF(); // error occurred
7227         return;
7228       }