軟盤結構 磁頭號和起始扇區的計算方法
軟盤結構(磁頭號和起始扇區的計算方法)
刺蝟@http://blog.csdn.net/littlehedgehog
;----------------------------------------------------------------------------; 函式名: 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
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
於淵 關於軟盤結構的這段筆墨惜得不是地方 ,其實很多看這種入門級書的讀者對於軟盤(磁碟)的結構認識大多都是不到位的。我在閱讀這段程式碼時也費了不少周折,最後發現其實是我對軟盤結構認識不足,補上這一課,這段程式碼就好讀多了。
3.5寸1.44M軟盤結構
1、 結構:2面、80道/面、18扇區/道、512位元組/扇區
扇區總數=2面 X 80道/面 X 18扇區/道 = 2880扇區
儲存容量= 512位元組/扇區X 2880扇區 = 1440 KB
2、 2 面: 編號0----1;
80道: 編號0----79 ;
18扇區:編號1----18 ;
這個很多書都有介紹,恕不細表。下面來看看軟盤中磁軌的安排,這會使我們感到很詫異——原來軟盤結構安排會是這樣。
3、相對扇區號:共2880個扇區,相對扇區號範圍為 0----2879
編號順序:
扇區物理號 相對扇區號
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
………
注意下紅色字,它表明軟盤的排列並不是按照我們所想象的"把0面先排完了再開始排1面,而是交替排列的"
4、物理扇區號(A,B,C)與相對扇區號(S)相互轉換公式:
頭/面(0--1) 道(0-79) 扇區 (1--18)
A B C
例如:A=1面 B= 15道 C=7扇區 這就是它的物理扇區號,現在進入關鍵問題——如何計算相對扇區呢?
計算相對扇區時,參照上面的軟盤結構排列表。我們應該清楚在15道之前,即0~14道里面,每道都有有18個扇區,而又0、1兩面都有磁軌,故而在0~14道有(0道----14道)*2面*18, 在計算第15道時,注意下我們要計算的15道是在1面,而1面之前的0面15道,有18個扇區,而在1面的15道磁軌中,有7個扇區。一共有0面的第15道18個扇區+1面第15道7個扇區-1,所以上述例子中的相對扇區號是(0道----14道)*2面*18+0面的第15道18個扇區+1面第15道7個扇區-1
有了上面的敘述,原始碼中除以18求出來商就是磁軌數,而餘數即是扇區數目,由於除以了18,那麼前面的結構表就可以如下表示:
0面,0道
1面,0道
0面,1道
1面,1道
0面,2道
1面,2道
.......
0面,12道
1面,12道
磁軌除以2表示當前物理磁軌號(因為是交替排列的!注意看上表的結構),而餘數就可以表示磁頭號。
於淵程式碼中間很多都是直接在暫存器中反覆玩弄彙編技巧,這段程式讓我看得相當鬱悶~ 自己改寫了一個,裡面用記憶體保留計算結果,這樣清晰很多:
以下是變數定義:
dbTrackNum db 0 ;磁軌數
dbSectorNum db 0 ;扇區數
dbdriverNum db 0 ;驅動器號
dbResistiveNum db 0 ;磁頭數
push dx
push bx
mov bl,[BPB_SecPerTrk]
div bl
inc ah
mov byte [dbSectorNum],ah
mov ah,al
shr al,1
mov byte [dbTrackNum],al
and ah,1b
mov byte [dbResistiveNum],ah
mov ah,2h
mov al,cl
mov dl,[dbdriverNum]
mov dh,[dbResistiveNum]
mov ch,[dbTrackNum]
mov cl,[dbSectorNum]
pop bx
.Reading:
int 13h
jc .Reading
pop dx
ret
不好意思,沒寫註釋,不過有了上面的解釋,我想這段程式碼應該是很好懂得~~
自己動手寫作業系統》讀書筆記系列