操作系统学习初步-软驱介绍及BIOS调用示例
软驱
1.4M的软盘两面均可记录信息,称为面0和面1。两面各有一个磁头可以记录和读取信息,两个磁头分别称为磁头0和磁头1。每面有80个同心圆磁道,从外向里称为磁道0…磁道79 。每个片面均分成18个扇面。扇面把磁道分成了更小的单元,每一小块称为一个扇区,一个扇区是512字节,面0磁道0有18个扇区,序号1…18,面1磁道0为19…36,然后磁道1开始排序。全盘容量为 5121880*2=1474560字节。
磁盘中断:INT 0x13
AH 0x0重置;0x2读盘;0x3写盘;0x4校验;0x5寻道
AL 读取对象占的扇区数(只能同时处理连续的扇区,意思是不能跨越磁道、磁头)
ES:BX 读出的数据存储在什么地方?
CH 磁道号(柱面号)
CL 从第几个扇区开始读
DH 磁头号(0或1)
DL 驱动器号,一般情形软驱是A盘,为0
FLAGS.CF 0,正确,AH == 0;1,错误,AH == 错误码
以下是一段读取软驱内容到指定物理内存的汇编代码。
该程序只能读取一张软盘。
程序参数:驱动器号,一般为0;需要读取的位置(指定内容在磁盘中的偏移,不是哪个扇区);读取内容的字节数;目标物理内存。
本段程序为GNU AS,AT&T语法格式。需要注意的是标识符大小写敏感的。
.macro FloppyRead driver,ReadPosition,ReadSize,Dest
JMP _FloppyReadEntry
_FLOPPY_VARS:
# 变量
head :.byte 0 #磁头号
cylinder :.byte 0 #柱面号
sector :.byte 1 #扇区号
once :.byte 1 #一次连续读取的扇区数
sectors :.word 1 #需要读取的扇区数目
PhyAddr:.long \Dest
Okay :.ascii "Read Success!"
_FloppyReadEntry:
# 求读取位置所在柱面扇区磁头信息
movl $\ReadPosition,%eax #读取位置/512获得扇区数目
movl $512,%ecx
xorl %edx,%edx # 真的要小心,这条指令不能少,不然结果不确定。EDX=0
divl %ecx
addl $1,%eax #余数为0时,读取位置还是要定位到下一扇区,譬如512,第一扇区为0..511,512 in sector2
GET_HEAD:
movl $36,%ecx # 正反2面共36个簇
xorl %edx,%edx # edx清0
divl %ecx
movb %al,cylinder
cmp $18,%edx # 余数为扇区数>18,磁头为1,扇区为(余数-18)
JNA GET_SECTOR
subl $18,%edx
movb $1,head
GET_SECTOR:
movb %dl,sector
# 求取需要读取的扇区数
movl $\ReadSize,%eax
xorl %edx,%edx
movl $512,%ecx
divl %ecx
addl $1,%eax
movw %ax,sectors
# 把 SI作为计数器,统计已经读取的扇区
movw $0,%si
_Retry:
# 求一次读入的扇区数
movb $19,%al
subb sector,%al
movb %al,once
# 把将要读取的扇区数加已经读完的扇区数相加和总数比较
movw %si,%bx
addb once,%bl
cmpw sectors,%bx
# 如果%bx<=sectors,直接进行读取
jbe _CallBios
# 如果超过了,把ONCE减去超过的数量,得到需要读取的数量
movw once ,%ax
subw sectors,%bx # 得到多余的数量 21-4=17
subw %bx,%ax
movb %al,once
_CallBios:
movw $0,%ax
movw %ax,%es
movw PhyAddr,%BX
movb head,%DH #磁头
movb $\driver,%DL #驱动器
movb cylinder,%CH #柱面
movb sector,%CL #扇区
movb $0x02,%AH
movb once,%AL #读入扇区数量
INT 0x13
nop
jc _CallBios
_Next:
add once,%si
cmp sectors,%si
#如果大于等于需要读取的扇区数,跳转到结束
jAE _READ_FINISH
_GO_ON:
# 将写入地址修改
movl $512,%eax
mull once
addl PhyAddr,%eax
movl %eax,PhyAddr
# 起始扇区重置1
#movb $1,sector
# 更换磁头
movb head,%al
not %al
and $1,%al
movb %al,head
#如果磁头由1->0,磁道加1
cmp $0,%al
jne _Retry
add $1,cylinder #如果cylinder>80,则需要更换磁盘
jmp _Retry
_READ_FINISH:
nop
movw $Okay,%bp /* ES:BP=字符串地址 */
movw $13,%cx /*字符串长度 */
movw $0x1301,%ax /*AH=0x13,AL=0x01 */
movw $0xC,%bx /*Page=0(BH=0)Black ground and red font(BL=0x0C,highlight)*/
movb $15,%dh /* Line */
movb $0,%dl /* col */
int 0x10
nop
.endm
今天的文章操作系统学习初步-软驱介绍及BIOS调用示例「建议收藏」分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88394.html