1) 前提知識:
- 說明
- 我用的是 DOSBox 0.74-3 啟動并運行的夯到,而且我沒有軟盤,因此我只能操作硬盤
- 直接向磁盤扇區(qū)寫入數(shù)據(jù)是危險的饮亏,很可能覆蓋掉重要的數(shù)據(jù)耍贾,所以千萬不要隨便對硬盤中的扇區(qū)進行寫入。文章中所有程序的功能都是從硬盤中讀取數(shù)據(jù)路幸。
- 從 硬盤中讀取數(shù)據(jù) 的測試代碼
文件名:pro174.asm
assume cs:code
code segment
; 程序功能:
; 讀取 0 面 0 道 1 扇區(qū)的內(nèi)容到 0:200
; 入口參數(shù):
; (ah)=13h 的功能號(2 表示讀扇區(qū))
; (al)=讀取的扇區(qū)數(shù)
; (ch)=磁道號
; (cl)=扇區(qū)號
; (dh)=磁頭號(對于軟盤即面號逼争,因為一個面用一個磁頭來讀寫)
; (dl)=驅(qū)動器號(軟驅(qū)從 0 開始:0 代表軟驅(qū)A,1 代表軟驅(qū)B劝赔;硬盤從 80h 開始,80h 代表硬盤C胆敞,81h 代表硬盤D)
; es:bx 指向接收從扇區(qū)讀入數(shù)據(jù)的內(nèi)存區(qū)
; 返回參數(shù):
; 操作成功:(ah)=0着帽,(al)=讀入的扇區(qū)數(shù)
; 操作失敗:(ah)=出錯代碼
start:
mov ax, 0
mov es, ax
mov bx, 200h ; es:bx 指向接收從扇區(qū)讀入數(shù)據(jù)的內(nèi)存區(qū)
mov ah, 2 ; int 13h 的功能號(2 號子程序表示讀扇區(qū))
mov al, 1 ; 讀取的扇區(qū)數(shù)
mov ch, 0 ; 磁道號
mov cl, 1 ; 扇區(qū)號
mov dh, 0 ; 磁頭號(對于軟盤即面號移层,因為一個面用一個磁頭來讀寫)
mov dl, 80h ; 驅(qū)動器號(軟驅(qū)從 0 開始:0 代表軟驅(qū)A仍翰,1 代表軟驅(qū)B;硬盤從 80h 開始观话,80h 代表硬盤C予借,81h 代表硬盤D)
int 13h
mov ax, 4c00h
int 21h
code ends
end start
2) 實驗17 正文:
- 思路
實驗要求是安裝一個新的 int 7ch 中斷例程,然后將傳入的 邏輯扇區(qū)號 轉化為 int 13h 中斷例程需要的入口參數(shù)频蛔,邏輯扇區(qū)號 算出物理編號的算法已經(jīng)給出灵迫,基本是除法操作,相對來說不算太難
- 實現(xiàn)代碼:
文件名:exp17.asm
assume cs:code
code segment
start:
mov ax, cs
mov ds, ax
mov si, offset int7ch ; 設置 ds:si 指向源地址
mov ax, 0
mov es, ax
mov di, 200h ; 設置 es:di 指向目的地址
mov cx, offset int7chend - offset int7ch ; 設置 cx 為傳輸長度
cld ; 設置傳輸方向為正
rep movsb
; 設置中斷向量表
mov ax, 0
mov es, ax
cli
mov word ptr es:[7ch * 4], 200h
mov word ptr es:[7ch * 4 + 2], 0
sti
mov ax, 4c00h
int 21h
; 新的 int 7ch 中斷例程晦溪,實現(xiàn)通過邏輯扇區(qū)號對軟盤進行讀寫
; 參數(shù)說明:
; 1. 用 ah 寄存器傳遞功能號:0 表示讀瀑粥,1 表示寫;
; 2. 用 dx 寄存器傳遞要讀寫的扇區(qū)的邏輯扇區(qū)號三圆;
; 3. 用 es:bx 指向存儲讀出數(shù)據(jù)或?qū)懭霐?shù)據(jù)的內(nèi)存區(qū)狞换。
int7ch:
cmp ah, 1
ja int7chret ; 當 ah 傳遞的功能號大于 1 則轉移
push cx
push dx
push si
push di ; 保護現(xiàn)場避咆,因為調(diào)用 int 13h,ax 會存儲讀寫操作的結果修噪,所以 ax 不需要入棧
mov di, ax ; 將傳遞進來的 功能號保存起來
mov ax, dx ; 將 邏輯扇區(qū)號 放到 ax 中查库,用于做除法操作
mov dx, 0 ; 除數(shù)為 16 位,因此被除數(shù)為 32 位黄琼,需要 ax 和 dx
mov si, 1440
div si ; 除數(shù)為 16 位樊销,則 AX 存儲除法操作的商,DX 存儲除法操作的余數(shù)
mov si, ax ; 將商保存起來
mov ax, dx ; 將余數(shù)放到 ax 中适荣,還需要做除法
mov cl, 18
div cl ; 除數(shù)為 8 位现柠,則 AL 存儲除法操作的商,AH 存儲除法操作的余數(shù)
mov ch, al ; 磁道號
mov cl, ah
inc cl ; 扇區(qū)號
mov ax, di ; ah 為傳遞進來的 功能號
add ah, 2 ; int 13h 的功能號
mov al, 1 ; 讀取的扇區(qū)數(shù)
mov dx, si
mov dh, dl ; 磁頭號(對軟盤即面號弛矛,因為一個面用一個磁頭來讀寫)
mov dl, 80h ; 驅(qū)動器號(軟驅(qū)從 0 開始:0 代表軟驅(qū)A够吩,1 代表軟驅(qū)B;硬盤從 80h 開始丈氓,80h 代表硬盤C周循,81h 代表硬盤D)
int 13h ; 調(diào)用 int 13h 來對磁盤進行讀寫
int7chret:
pop di
pop si
pop dx
pop cx ; 恢復現(xiàn)場
iret
int7chend:
nop
code ends
end start
- 新的 int 7ch 中斷例程測試代碼:
文件名:exp17d.asm
assume cs:code
code segment
start:
mov ah, 0 ; 用 ah 寄存器傳遞功能號:0 表示讀,1 表示寫
mov dx, 0 ; 用 dx 寄存器傳遞要讀寫的扇區(qū)的邏輯扇區(qū)號
mov bx, 0
mov es, bx
mov bx, 200h ; 用 es:bx 指向存儲讀出數(shù)據(jù)或?qū)懭霐?shù)據(jù)的內(nèi)存區(qū)
int 7ch ; 調(diào)用新的 int 7ch 中斷例程
mov ax, 4c00h
int 21h
code ends
end start
-
代碼調(diào)試示意圖: