0.准备
- 再读取u盘这一节中,花费了一个月时间才成功,看到网站上有些博主说使用fat12文件格式的u盘,然后改下读取u盘的chs就能成功,有些博主说要用fat32文件格式的,再改chs也可以。我试了很久都不成功,实践证明还是要原理掌握了,才能实验成功。
- 先说下fat12文件格式的程序中的地址为什么是0xc200,0x4200+0x8000,0x8000是我们指定的内存读取地址,那么0x4200是怎么来的?软盘的fat12格式排布是:隐藏扇区+保留扇区+fat表*fat表占的扇区数+根目录占的扇区数=0+1+2*9+14=33,每个扇区512字节,33*512=16896,换算成十六进制正好是0x4200。参考博客DIY操作系统(一)
- 那么对于u盘,fat32文件格式的排布是FAT32文件系统学习(1) —— BPB的理解:引导扇区+保留扇区+fat表+数据区。也就是说我们要从数据区读入u盘的数据。数据区在u盘的chs的什么位置了?我们可以使用diskgenius工具查看u盘的结构,可以看到u盘的总的chs以及数据区起始扇区号。
我们可以点击扇区编辑,选择往后一个扇区号30697
地址0xEFD200的数据是42
1.代码验证
MOV AX,0x0820
MOV ES,AX
MOV CH,1
MOV DH,232
MOV CL,17
MOV [0x7dfe], DL
- 前两句是选择内存的首地址,为什么是0x0820而不是0x8200这是intel的工程师为了向后兼容这么做了,电脑上电进入bios程序进入实模式访问的是实际物理地址,但是寄存器是16位了,最大可以访问到0xffff,也就是能访问64kb。当时已经有1M的内存了,所以工程师为了不浪费资源,通过将ES的值左移4位再加上BX的值作为内存地址即可访问1M的地址,ES=0xffff,BX=0xf.生成的地址就是0xfffff。书中选择0x8200作为内存首地址,就是将ES=0x820,然后BX=0x0
- 接下来三句选择u盘的数据起始扇区号,将这个扇区号的数据加载进入内存
- 最后一句选择驱动器,也就是选择从软盘启动还是从硬盘启动,参考一些博客将其放入地址[0x7dfe],然后再取出来即可
MOV AX,ES
ADD AX,0x0020
MOV ES,AX
ADD CL,1
CMP CL,63
JBE readloop
MOV CL, 1
ADD DH, 1
CMP DH, 6
JB readloop
push ds
mov ax, 0x820
mov ds, ax
mov bx, 0x0
mov dl, [bx]
mov dh, 0xff
call dispreg16
JMP fin
- 第一部分就是书中的一个扇区一个扇区的读取,第二段就是读完一个磁头,读下一个磁头,参考博客Linux(ubuntu)下30天自制os学习引导,第3.2天(读取u盘上189kB的内容 )
- 第三部分我们读取内存首地址的数据,赋给dx的低8位,高8位我们赋值位0xff,与上面再diskgenius得到的比较是否为0x42