#汇编读取硬盘数据read_hard_disk_0
使用LBA28来访问硬盘
从硬盘读取逻辑扇区的步骤如下:
1、设置要读取的扇区数量
mov dx,0x1f2
mov al,1
out dx,al
此处设置要读取的扇区数量为1,如果设置为0,则表示要读取256个扇区(因为是使用的是al,表示该端口为8位宽)
2、设置要写入的起始LBA扇区编号
扇区编号长度为28,在4个8位宽的端口中分别写入(0x1f3, 0x1f4, 0x1f5, 0x1f6)写入0~23位
inc dx ;0x1f3
pop eax
out dx,al ;LBA地址7~0
inc dx ;0x1f4
mov cl,8
shr eax,cl
out dx,al ;LBA地址15~8
inc dx ;0x1f5
shr eax,cl
out dx,al ;LBA地址23~16
inc dx ;0x1f6
shr eax,cl
or al,0xe0 ;第一硬盘 LBA地址27~24
out dx,al
0x1f6端口,低4位为0,表示扇区编号的第24~27,高4位为e,即1110
前三位表示LBA模式,第四位0表示主硬盘1表示副硬盘
3、写入硬盘读写命令
inc dx ;0x1f7
mov al,0x20 ;读命令
out dx,al
4、检测端口状态
0x1f7端口即是命令端口又是状态端口
在硬盘操作期间,会将0x1f7端口的第7位置为1,表示处于“忙”状态
如果可以进行操作,则该bit位会清零并将第3位设置为1,表示ready
.waits:
in al,dx
and al,0x88
cmp al,0x08
jnz .waits ;不忙,且硬盘已准备好数据传输
and al, 0x88指令对al和0x88进行与操作
0x88的二进制形式为10001000,也就是我们关心的第3位和第7位
如果第7位为0,且第3位为1,也就是00001000(0x08)
那么就说明硬盘已经可以进行操作了
5、连续读取数据
0x1f0为硬盘的数据端口,16位的宽端口
我们可以通过这个端口读取或者写入数据
mov ecx,256 ;总共要读取的字数
mov dx,0x1f0
.readw:
in ax,dx
mov [ebx],ax
add ebx,2
loop .readw