(第4章 1)软盘结构及其数据读取

参考资料:

http://blog.csdn.net/smallmuou/article/details/6796867

 

        由于后面的汇编中要读取软盘扇区,这里抽空学习一下软盘结构和软盘读取。


(第4章 1)软盘结构及其数据读取_第1张图片
 1. 软盘结构

     1.44MB软盘容量计算:

     1.44MB=2(面) * 80(磁道/面) * 18(扇区/磁道) * 512(byte/扇区)

2. 相对扇区号及转换

     在系统中,于是可以通过“盘面+磁道+扇区”访问到相应内容,但是这样比较繁琐,于是有了“(相对)扇区号”的概念。(相对)扇区号实际上是从0开始对磁盘上所有扇区进行的编号。

 

 

扇区物理号               相对扇区号 

0面,0道,1扇区             0   

0面,0道,2扇区             1   

0面,0道,3扇区             2   

…………………….                 

0面,0道,18扇区           17 

1面,0道,1扇区            18 

……………

1面,0道,18扇区           35 

0面,1道,1扇区            36  

...................                               

0面,1道,18扇区           53 

1面,1道,1扇区            54 

...................

 

      可见,软盘扇区号不是我们想象的先排完1面,而是交替排列的。也可以认为是先编完0磁道上的扇区号,然后再编完1磁道上的扇区号,...,最后编完79磁道上的扇区号

 

      调用int 13h读取软盘扇区时,要求通过“指定的扇区号”计算出“柱面号(即磁道号)”、“磁头号(即盘面号)”、“起始扇区号(即是某个磁道上的第几个扇区)”。稍微想想就可以出来了,不必赘述。

 

 

3、软盘读写

在系统中,是怎么读和写软盘?

通过BIOS中断13,详细见下图:


(第4章 1)软盘结构及其数据读取_第2张图片

其中:

磁盘号:指的是软盘中的磁道或磁柱;

扇区号:指的是软盘的扇区;

CH存放磁道的低8位,CL的高两位存放磁道的高2位,CL的低6位存放扇区

磁头号:指的是软盘中的盘面;

驱动器号:指具体的软盘,如软盘A,软盘B...

CF为1则表示读取错误;

 

注:读磁盘时,将读到的扇区放到[es:bx]开始的内存中;

        写磁盘时,将[es:bx]开始的一个扇区写到磁盘上。

        这两处,[es:bx]都称为“数据缓冲区”

 

4. 实例

 

;----------------------------------------------------------------------------
; 函数名: ReadSector
;----------------------------------------------------------------------------
; 作用:
;    从第 ax 个 Sector 开始, 将 cl 个 Sector 读入 es:bx 中
ReadSector:
    ; -----------------------------------------------------------------------
    ; 怎样由扇区号求扇区在磁盘中的位置 (扇区号 -> 柱面号, 起始扇区, 磁头号)
    ; -----------------------------------------------------------------------
    ; 设扇区号为 x
    ;                           ┌ 柱面号 = y >> 1
    ;       x           ┌ 商 y ┤
    ; -------------- => ┤      └ 磁头号 = y & 1
    ;  每磁道扇区数     │
    ;                   └ 余 z => 起始扇区号 = z + 1
    push    bp
    mov    bp, sp
    sub    esp, 2            ; 辟出两个字节的堆栈区域保存要读的扇区数: byte [bp-2]

    mov    byte [bp-2], cl
    push    bx            ; 保存 bx
    mov    bl, [BPB_SecPerTrk]    ; bl: 除数
    div    bl            ; y 在 al 中, z 在 ah 中
    inc    ah            ; z ++
    mov    cl, ah            ; cl <- 起始扇区号
    mov    dh, al            ; dh <- y
    shr    al, 1            ; y >> 1 (其实是 y/BPB_NumHeads, 这里BPB_NumHeads=2)
    mov    ch, al            ; ch <- 柱面号
    and    dh, 1            ; dh & 1 = 磁头号
    pop    bx            ; 恢复 bx
    ; 至此, "柱面号, 起始扇区, 磁头号" 全部得到 ^^^^^^^^^^^^^^^^^^^^^^^^
    mov    dl, [BS_DrvNum]        ; 驱动器号 (0 表示 A 盘)
.GoOnReading:
    mov    ah, 2            ; 读
    mov    al, byte [bp-2]        ; 读 al 个扇区
    int    13h
    jc    .GoOnReading        ; 如果读取错误 CF 会被置为 1, 这时就不停地读, 直到正确为止

    add    esp, 2
    pop    bp

    ret
 

 

 

 

 

你可能感兴趣的:(数据)