今天要做什么?
(1)分享
我們上面已經說過INT 0x13這種指令(調用BIOS的INT指令),我們知道這是調用BIOS的0x13函數,但還不明白它到底是干什么用的:
AH = 0x02;# 讀盤
AH = 0x03;# 寫盤
AH = 0x04 ;# 校驗
AH = 0x0c;# 尋道
AL = 處理對象的扇區數;(只能同時處理連續的扇區)
CH = 柱面號;&0xff;
CL = 扇區號(0-5)|(柱面號&0x300)》》2;
DH = 磁頭號;
DL = 驅動器號;
ES:BX = 緩沖地址;(校驗及尋道時不使用)
返回值:
FLASC.CF ==0: 沒有錯誤,AH==0
FLAGS.CF ==1:有錯誤,錯誤號碼存入AH內(與重置(reset)功能一樣)
我們這次用的是AH =0x02,是讀盤的意思。
返回值那一欄里的FLACS.CF 意識是進位標志,也就是說,調用這個函數后,如果沒錯,進位標志就是0,如果有錯,進位標志就是1.
進位標志是一個只能儲存1位信息的寄存器,除此之外,CPU還有其他幾個只有1位的寄存器,像這種1位寄存器我們稱之為標志(在英文中就是flag)。
如果有軟盤,希望大家能把他拆開看看,拆開后可以看到,中間有黑色圓盤(磁性膠片),環狀區域有80個柱面。我們有正面(磁頭0)和反面(磁頭1號)兩個磁頭。軟盤分為18份,每一份稱為一個扇區,一個圓環有18個扇區。
綜上所述。一個軟盤有80個柱面,2個磁頭,18個扇區,且一個扇區有512字節。
一張軟盤的容量是:80*2*512 = 1474560 Byte =1440KB
含有IPL的啟動區,位于C0-H0-S1(柱面0,磁頭0,扇區1的縮寫),寫一個扇區是C0-H0-S2,待會要對這個扇區進行操作。
緩沖區地址:這是個內存地址,表明我們要把從軟盤上讀出的數據裝載到內存的哪個位置。
如果能用一個寄存器來表示內存地址的話,會很方便,但是一個BX只能表示0-oxffff的值,也就是0-65535,最大才65536/1024=64k,64k內存太小了。
為了解決這個問題,新增了一個EBX的寄存器(最大4G)內存,在中間的過渡時期是設計了一個起輔助作用的段寄存器(segment register)用ES:BX(MOV AL,[ES,BX])這種方式來表示地址(理解:先用ES寄存器指定一個大致的地址,然后再用BX來指定其中一個具體地址)
16位實模式下的地址線通常是20位,也就是(最大尋址)oxfffff。當計算地址超過這個范圍時,會發生回繞(因處理器不同)
段位寄存器的計算需要先把值賦值給通用寄存器。
0xFFFF*16+oxffff = 1114095 =>0xffff0+0xffff = 0x10ffef
常用用法(DS可以省略,所以DS必須先指定為0,否則地址就要加上這個數的16倍)
MOV CX,[1234],其實是MOV CX,[DS:1234];
MOV AL,[SI] 也就是 MOV AL,[DS:SI]的意思
在正常程序中,要讀下一個扇區,只需要給CL+1,給ES 加上0x20(扇區大小512/16進制)就行了。CL是扇區號,ES指定讀入地址。
C0-H0-S18的下一扇區,是磁盤反面的C0-H1-SQ,從0xa400讀入吧
指令JB:條件跳轉指令(jump if below)意思差不多是 如果小于的話,就跳轉
指令EQU:相當于C語言的#define命令,用來聲明常量,用來聲明常數。
“CYLS EQU 10”意思是“CYLS = 10”.EQU是equal的縮寫
輔導資源 第三天的筆記,建議手打!!!
?
; haribote-ipl
; TAB =4
CYLS ? ?EQU ? ? 10 ? ? ? ? ? ? ? ?; 聲明CYLS=10
? ? ? ? ORG ? ? 0x7c00 ? ? ? ? ? ?; 指明程序裝載地址
; 標準FAT12 格式軟盤專用的代碼 Stand FAT12 format flppy code
? ? ? ? JMP ? ? entry
? ? ? ? DB ? ? ?0x90
? ? ? ? DB ? ? ?"HARIBOTE" ? ? ? ?;啟動扇區名稱(8字節)
? ? ? ? DW ? ? ?512 ? ? ? ? ? ? ? ;每個扇區(sector)大小(必須512字節)
? ? ? ? DB ? ? ?1 ? ? ? ? ? ? ? ? ; 簇(cluster)大小 必須為一個扇區
? ? ? ? DW ? ? ?1 ? ? ? ? ? ? ? ? ; FAT起始位置(一般為第一個扇區)
? ? ? ? DB ? ? ?2 ? ? ? ? ? ? ? ? ; FAT個數(必須為2)
? ? ? ? DW ? ? ?224 ? ? ? ? ? ? ? ; 根目錄大小(一般為224項)
? ? ? ? DW ? ? ?2880 ? ? ? ? ? ? ?; 該磁盤大小(必須為2880扇區1440*1024/512)
? ? ? ? DB ? ? ?0xf0 ? ? ? ? ? ? ?; 跳過引導扇區,必須為0xf0
? ? ? ? DW ? ? ?9 ? ? ? ? ? ? ? ? ; 跳過引導扇區后的第一個數據分區,必須為9?
? ? ? ? DW ? ? ?18 ? ? ? ? ? ? ? ?; 該磁盤的扇區數,必須為18
? ? ? ? DW ? ? ?2 ? ? ? ? ? ? ? ? ; 磁頭每個扇區扇區數,必須為2?
? ? ? ? DD ? ? ?0 ? ? ? ? ? ? ? ? ;不適用分區,必須為0
? ? ? ? DD ? ? ?2880 ? ? ? ? ? ? ?;重寫一次磁盤大小
? ? ? ? DB ? ? ?0,0,0x29 ? ? ? ? ?;磁盤號,卷標,磁盤長度??必須為0x29
? ? ? ? DD ? ? ?0xffffffff ? ? ? ?;磁盤序列號,必須為0xffffffff
? ? ? ? DB ? ? ?"HARIBOTEOS " ? ? ;磁盤名稱,必須為11字,不足填空格
? ? ? ? DB ? ? ?"FAT12 ? " ? ? ? ?;磁盤格式名稱(必須為8字?,不足填空格)
? ? ? ? RESB ? ?18 ? ? ? ? ? ? ? ?;先空出18字節
; 程序主體
entry:
? ? MOV AX,0 ? ? ? ? ? ? ? ? ? ? ? ;初始化寄存器
? ? MOV SS,AX
? ? MOV SP,0x7c00
? ? MOV DS,AX
;讀磁盤 讀入10個柱面
? ? MOV AX, 0x0820
? ? MOV es,AX
? ? MOV CH,0 ? ? ? ? ; 柱面0
? ? MOV DH,0 ? ? ? ? ; 磁頭
? ? MOV CL,2 ? ? ? ? ; 扇區2
readloop:
? ? MOV SI,0 ? ? ? ? ; 緩沖區偏移 記錄失敗次數
retry:
? ? MOV AH,0x02 ? ? ?; 讀入磁盤
? ? MOV AL,1 ? ? ? ? ; 1個扇區
? ? MOV bx,0 ? ? ? ? ;0
? ? MOV dl,0X00 ? ? ? ; A驅動器
? ? INT 0x13 ? ? ? ? ; 調用磁盤BIOS
? ? JNC next ? ? ? ?;沒出錯時跳轉到next
? ? ADD SI,1 ? ? ? ?;SI加1
? ? CMP SI,5 ? ? ? ?;比較SI與5
? ? JAE error ? ? ? ?;SI>5時,跳轉到error
? ? MOV AH,0x00 ? ? ?
? ? MOV DL,0x00 ? ? ?;A驅動器
? ? INT 0x13 ? ? ? ?;重置驅動器
? ? JMP retry
next:
? ? MOV AX,ES ? ? ? ;把內存地址后移0x200
? ? ADD AX,0X0020 ? ;往CL里加1
? ? MOV ES,AX ? ? ? ;因為沒有ADD ES,0x020指令,所以這里稍微繞個彎
? ? ADD CL,1 ? ? ? ?;CL加1
? ? CMP CL,18 ? ? ? ;比較CL與18
? ? JBE readloop ? ?;如果CL<=18.則跳轉至readloo
? ? MOV CL,1
? ? ADD DH,1
? ? CMP DH,2
? ? JB readloop ? ? ; 如果DH<2,則跳轉到readloop
? ? MOV DH,0
? ? ADD CH,1
? ? CMP CH,cyls
? ? JB readloop ? ;如果CL <=18跳轉到readloop
; 讀取完畢,跳轉到haribote.sys執行!
? ? ? ? MOV ? ? [0x0ff0],CH ? ? ; IPLがどこまで読んだのかをメモ
? ? ? ? JMP ? ? 0xc200
error:
? ? ? ? MOV ? ? SI,msg
putloop:
? ? ? ? MOV ? ? AL,[SI]
? ? ? ? ADD ? ? SI,1 ? ? ? ? ? ?; 給SI加1
? ? ? ? CMP ? ? AL,0
? ? ? ? JE ? ? ?fin
? ? ? ? MOV ? ? AH,0x0e ? ? ? ? ; 顯示一個文字
? ? ? ? MOV ? ? BX,15 ? ? ? ? ? ; 指定字符顏色
? ? ? ? INT ? ? 0x10 ? ? ? ? ? ?; 調用顯卡BIOS
? ? ? ? JMP ? ? putloop
fin:
? ? ? ? HLT ? ? ? ? ? ? ? ? ? ? ; 讓CPU停止,等待指令
? ? ? ? JMP ? ? fin ? ? ? ? ? ? ; 無限循環
msg:
? ? ? ? DB ? ? ?0x0a, 0x0a ? ? ?; 換行兩次
? ? ? ? DB ? ? ?"load error"
? ? ? ? DB ? ? ?0x0a ? ? ? ? ? ?; 換行
? ? ? ? DB ? ? ?0
? ? ? ? RESB ? ?0x7dfe-$ ? ? ? ?; 填寫0x00直到0x001fe
? ? ? ? DB ? ? ?0x55, 0xaa
本人今天上班,所以分享較少,后面多多加油!