要理解这段,先看下面的示意图(参照原书图8-11画的)
inc dx
;0x1f6
mov al,0xe0
;LBA28模式,主盘
or al,ah
;LBA地址27~24
out dx,al
mov al,0xe0 表示选择LBA模式,选择主硬盘
注意,在调用这个过程的时候,DI:SI=起始逻辑扇区号,DI的低四位是有效的,高四位应该为0,其实这里我觉得应该加一句,
mov al,0xe0
这句后面加一句 and ah,0x0f
目的是把DI的高四位清零,万一调用者忘记清零了,这样做可以防止意外发生。
当把起始LBA扇区号设置好后,就可以发出读命令了。上面的代码表示向端口0x1F7写入0x20,请求读硬盘。
接下来等待读请求完成。端口0x1F7既是命令端口,也是状态端口。部分状态位的含义如图:
一旦硬盘准备好了,就可以读取数据了。0x1F0是硬盘接口的数据端口,是16位的。可以连续从这个端口读取数据。
mov cx,256
in ax,dx
这两句话就表示读取了一个字的数据(16位)到AX中
现在我们再回到那部分代码,就很容易理解了。
xor di,di ;di清零 (因为我们传入逻辑扇区号是100,不超过16 bits) mov si,app_lba_start ;程序在硬盘上的起始逻辑扇区号 xor bx,bx ;加载到DS:0x0000处 call read_hard_disk_0执行到这里,内存大概如下图所示: