int 0x13 中斷理解

int 0x13中斷向量所指向的中斷服務程序實質上就是磁盤服務程序。

用途:將指定扇區的代碼加載到內存的指定位置。

因此,在使用int 0x13中斷時要將參數傳遞給服務程序:
例如:將指定扇區和加載的內存位置傳遞給服務程序

傳遞參數的方式:通過幾個通用寄存器實現


oad_setup:
mov dx,#0x0000 ! drive 0, head 0
mov cx,#0x0002 ! sector 2, track 0
mov bx,#0x0200 ! address = 512, in INITSEG
mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors
int 0x13 ! read it
jnc ok_load_setup ! ok - continue
mov dx,#0x0000
mov ax,#0x0000 ! reset the diskette
int 0x13
j load_setu

INT 13H這類軟件中斷指令,功能上是帶有現場狀態保存和斷點地址保存的無條件轉移指令。

執行這條指令時,它做這幾件事:
1. 將CPU內的標誌寄存器內容壓入堆棧,用來保存斷點的現場狀態。
2. 將斷點的地址(CS和IP寄存器的當前值)壓入堆棧保存,以保存返回所需的斷點地址。
3. 按中斷號取得中斷向量,並無條件跳轉到中斷向量所指向的目標地址。
此後,CPU就進入中斷服務程序去運行它的程序了。而中斷服務程序最後會有一條IRET中斷返回指令,通過它恢復現場返回斷點,程序繼續執行INT 指令後面的程序指令。

關於你的兩個疑問:
(1)CPU轉去執行了BIOS中的相應指令,說得沒錯。
內存並不只指RAM內存條,ROM也是內存的一部分。
在DOS下,RAM只佔用1M地址空間的前640KB,還有384KB系統保留的地址,其中的一部分就是給ROM用的。
ROM中的BIOS程序,是CPU可以直接執行的程序指令。
你電腦開機時,CPU最初執行的POST自檢程序,也是在ROM中的。
而ROM中的BIOS(基本輸入輸出系統)本來就是讓電腦在工作中隨時調用的功能性子程序的合集。


BIOS中斷INT 0x13中,

ah=0x02,即爲讀磁盤扇區到內存,利用這二號服務即可讀入setup模塊。

調用此功能將從磁盤上把一個或更多的扇區內容讀進存貯器。因爲這是一個
低級功能,在一個操作中讀取的全部扇區必須在同一條磁道上(磁頭號和磁道號
相同)。BIOS不能自動地從一條磁道末尾切換到另一條磁道開始,因此用戶必須
把跨多條磁道的讀操作分爲若干條單磁道讀操作。

入口參數:
AH=02H 指明調用讀扇區功能。
AL 置要讀的扇區數目,不允許使用讀磁道末端以外的數值,也不允許使該寄存器爲0。

CH 磁道號的低8位數。

CL 低5位放入所讀起始扇區號,位7-6表示磁道號的高2位。cl=開始扇區(位0—5),磁道號高二位(位6—7)

DL 需要進行讀操作的驅動器號。dl=驅動器號(若是硬盤則要置位7)
DH 所讀磁盤的磁頭號。
dh=磁頭號

es:Bx—>指向數據緩衝區   ES:BX 讀出數據的緩衝區地址。

若出錯則CF示志置位

返回參數:
如果CF=1,AX中存放出錯狀態。讀出後的數據在ES:BX區域依次排列

BOOTSEG equ 0x07c0 ;boot.bin 被bios加載到0x7c00內存處
SYSSEG equ 0x1000 ;kernel先被加載到0x10000,再移動到0x0處
SYSLEN equ 17 ;內核最多佔用17個扇區 17*512字節
KERNEL_CS equ 0x08 ;內核代碼段選擇符
start:
     jmp 0x07c0:go ;這條指令將cs寄存器設爲0x07c0,便於尋址
go:
     mov ax,cs
     mov ds,ax
     mov es,ax
     mov ss,ax
     mov sp,0x400 ;開闢棧空間邏輯地址0x400-0x200用作棧空間,0x200-0x00用於存放boot.bin
上面的代碼先用一個jmp跳轉指令將cs寄存器的內容置爲0x07c0,並同步給ds,es,ss.這是爲了便於後面尋址,這樣後面用label(比如load_kernel作爲偏移地址時就是實際的物理地址,因爲這段程序被加載到0x7c00處,就相當於cs*16 + label = 0x7c00 + label偏移).然後sp賦值爲0x400,由於這段程序本身佔一個扇區0x200,所以棧空間可用爲0x200.
load_kernel:
     mov dx,0x0000 ;DH is head,DL is driver  
     mov cx,0x0002; CL 6,7位是磁道號高2位.位5~0是起始扇區號(從1開始)
     mov ax,SYSSEG
     mov es,ax ;讀入緩衝區基址0x1000
 
     xor bx,bx
     mov ax,0x200 + SYSLEN ;AH-讀扇區功能號(2);AL-需要讀的扇區數(17,即第一柱面除去第1個扇區(是boot.s),剩餘的17個扇區是kernel.bin)
     int 0x13
     jnc load_ok; 如果有錯誤, CF位會被置位
load_fail: jmp load_fail ;死循環


、、、

load_setup:
mov dx,#0x0000 !驅動器0,磁頭0;
mov cx,#0x0002 !扇區2,磁道0;
mov bx,#0x0200 !此時es已置爲0x9000,則指向地址0x9200;
mov ax,#0x0200+SETUPLEN !置爲服務二,讀入SETUPLEN=4個扇區;
int 0x13 !中斷13;
jnc ok_load_setup !判斷是否成功;
mov dx,#0x0000 !未成功,復位磁盤;
mov ax,#0x0000 
int 0x13
j load_setup !繼續讀;
ok_load_setup:


INT 13H,AH=03H 寫扇區

說明:
調用此功能將從磁盤上把一個或更多的扇區內容寫入驅動器。因爲這
是一個低級功能,在一個寫入操作中的全部扇區必須在同一條磁道上(磁
頭號和磁道號相同)。BIOS不能自動地從一條磁道末尾切換到另一條磁道
開始,因此用戶必須把跨多條磁道的寫操作分爲若干條單磁道寫操作。
入口參數:
AH=03H 指明調用寫扇區功能。
AL 置要寫的扇區數目
,不允許使用超出磁道末端以外的數值,
也不允許使該寄存器爲0。
DL 需要進行寫操作的驅動器號。
DH 所寫磁盤的磁頭號。
CH 磁道號的低8位數。
CL 低5位放入所讀起始扇區號,位7-6表示磁道號的高2位

ES:BX 放置寫入數據的存貯區地址。
返回參數:
如果CF=1,AX中存放出錯狀態。
詳情請參見磁盤錯誤狀態返回碼一文。
示例:
C_SEG SEGMENT PUBLIC
ASSUME CS:C_SEG,DS:C_SEG
ORG 100H
START: JMP WRITE
BUFFER DB 512 DUP(0FFH)
WRITE: PUSH CS
POP ES
MOV BX, OFFSET BUFFER
MOV AX, 0301H
MOV CX, 0001H
MOV DX, 0000H
INT 13H
;寫入軟盤A, 0面0道1扇區
;把此扇區數據全部置爲0FFH
JC ERROR
……
ERROR: ……
C_SEG ENDS
END START

發佈了32 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章