我指的是BrokenThorn的操作系统开发教程,目前正在阅读有关开发第二阶段的完整第一阶段引导加载程序的部分 - Bootloaders 4。
在将逻辑块地址(LBA)转换为Cylinder-Head-Sector(CHS)格式的部分中,这是使用的代码 -
LBACHS:
xor dx, dx ; prepare dx:ax for operation
div WORD [bpbSectorsPerTrack] ; divide by sectors per track
inc dl ; add 1 (obsolute sector formula)
mov BYTE [absoluteSector], dl
xor dx, dx ; prepare dx:ax for operation
div WORD [bpbHeadsPerCylinder] ; mod by number of heads (Absolue head formula)
mov BYTE [absoluteHead], dl ; everything else was already done from the first formula
mov BYTE [absoluteTrack], al ; not much else to do :)
ret
我无法理解这种转换背后的逻辑。我尝试使用一些示例值来浏览它,看看它是如何工作的,但这让我更加困惑。有人可以解释这种转换是如何工作的以及使用的逻辑吗?
答案 0 :(得分:1)
我猜你的LBA值存储在AX
中,因为你正在对某个值进行除法。
作为一些预先信息,absoluteSector
是CHS扇区号,absoluteHead
是CHS头号,absoluteTrack
是CHS柱号。气缸和轨道完全相同,只是一个不同的名称。
此外,16位代码的DIV
操作将采用DX:AX
寄存器组合中的任何内容并将其除以某个值。除法的其余部分将在DX
寄存器中,而实际结果将在AX
寄存器中。
接下来,*X
寄存器是16位寄存器,其中*
是ABCD
之一。它们由低和高分量组成,分别对于高和低分别称为*H
和*L
。例如,DX
寄存器的高8位为DH
,低8位为DL
。
最后,因为BYTE
和WORD
修饰符只是说明将要使用/传输的数据的大小。
您必须提取的第一个值是扇区号,它是通过将LBA值乘以每个磁道的扇区数得到的。然后DL
寄存器将包含扇区号减1。这是因为计数扇区从1开始,这与从零开始的大多数值不同。为了解决这个问题,我们在DL
寄存器中添加一个得到正确的扇区值。该值存储在absoluteSector
的内存中。
您必须提取的下一个值是头部编号,它是通过将最后DIV
操作的结果除以每个气缸的头数得到的。然后,DL
注册将包含头号,我们将其存储在absoluteHead
。
最后,我们得到了曲目编号。在最后一个除法中,我们已经获得了AL
寄存器中的值。然后,我们将此值存储在absoluteTrack
。
希望这可以解决一些问题。
-Adrian