匯編語言(第3版,王爽著):實(shí)驗(yàn)17 編寫包含多個(gè)功能子程序的中斷例程

實(shí)驗(yàn)17 編寫包含多個(gè)功能子程序的中斷例程

1) 前提知識:

  1. 說明
  1. 我用的是 DOSBox 0.74-3 啟動并運(yùn)行的,而且我沒有軟盤,因此我只能操作硬盤
  2. 直接向磁盤扇區(qū)寫入數(shù)據(jù)是危險(xiǎn)的,很可能覆蓋掉重要的數(shù)據(jù),所以千萬不要隨便對硬盤中的扇區(qū)進(jìn)行寫入。文章中所有程序的功能都是從硬盤中讀取數(shù)據(jù)
  1. 從 硬盤中讀取數(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)=磁頭號(對于軟盤即面號,因?yàn)橐粋€(gè)面用一個(gè)磁頭來讀寫)
    ;     (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)=出錯(cuò)代碼
    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           ; 磁頭號(對于軟盤即面號,因?yàn)橐粋€(gè)面用一個(gè)磁頭來讀寫)
        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
從 硬盤中讀取數(shù)據(jù) 的測試代碼的調(diào)試過程
讀取硬盤失敗的情況

2) 實(shí)驗(yàn)17 正文:

  1. 思路

實(shí)驗(yàn)要求是安裝一個(gè)新的 int 7ch 中斷例程,然后將傳入的 邏輯扇區(qū)號 轉(zhuǎn)化為 int 13h 中斷例程需要的入口參數(shù),邏輯扇區(qū)號 算出物理編號的算法已經(jīng)給出,基本是除法操作,相對來說不算太難

  1. 實(shí)現(xiàn)代碼:

文件名:exp17.asm

assume cs:code

code segment
    start:
        mov ax, cs
        mov ds, ax
        mov si, offset int7ch                       ; 設(shè)置 ds:si 指向源地址
        mov ax, 0
        mov es, ax
        mov di, 200h                                ; 設(shè)置 es:di 指向目的地址
        mov cx, offset int7chend - offset int7ch    ; 設(shè)置 cx 為傳輸長度
        cld                                         ; 設(shè)置傳輸方向?yàn)檎?        rep movsb

        ; 設(shè)置中斷向量表
        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 中斷例程,實(shí)現(xiàn)通過邏輯扇區(qū)號對軟盤進(jìn)行讀寫
    ; 參數(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         ; 當(dāng) ah 傳遞的功能號大于 1 則轉(zhuǎn)移

        push cx
        push dx
        push si
        push di             ; 保護(hù)現(xiàn)場,因?yàn)檎{(diào)用 int 13h,ax 會存儲讀寫操作的結(jié)果,所以 ax 不需要入棧

        mov di, ax          ; 將傳遞進(jìn)來的 功能號保存起來
        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 為傳遞進(jìn)來的 功能號
        add ah, 2           ; int 13h 的功能號
        mov al, 1           ; 讀取的扇區(qū)數(shù)
        mov dx, si
        mov dh, dl          ; 磁頭號(對軟盤即面號,因?yàn)橐粋€(gè)面用一個(gè)磁頭來讀寫)
        mov dl, 80h         ; 驅(qū)動器號(軟驅(qū)從 0 開始:0 代表軟驅(qū)A,1 代表軟驅(qū)B;硬盤從 80h 開始,80h 代表硬盤C,81h 代表硬盤D)

        int 13h             ; 調(diào)用 int 13h 來對磁盤進(jìn)行讀寫

    int7chret:
        pop di
        pop si
        pop dx
        pop cx              ; 恢復(fù)現(xiàn)場
        iret

    int7chend:
        nop
code ends

end start
  1. 新的 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
  1. 代碼調(diào)試示意圖:


    實(shí)驗(yàn)17 代碼調(diào)試示意圖
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容