1. P52,47~56
start :
mov ax, #BOOTSEG
mov ds, ax
mov ax, #INITSEG
mov es, ax
mov cx, #256
sub si, si
sub di, di
rep ! 重復(fù)執(zhí)行它的下一條語(yǔ)句movw,直到cx中的數(shù)值為0。這里是循環(huán)執(zhí)行256次
movw ! 以字節(jié)為單位,從源地址往目的地址搬移數(shù)據(jù),si、di自增
jmpi go,INITSEG ! jmpi--段間跳轉(zhuǎn)指令,CS = INITSEG,IP = go,即跳轉(zhuǎn)到INITSEG:go處執(zhí)行
標(biāo)志寄存器EFlags
方向標(biāo)志DF(Direction Flag),用于決定執(zhí)行完一次串操作之后,變址寄存器ESI/EDI是加還是減
- DF=0,自加
- DF=1,自減
串操作
- 取串(LODS),存串(STOS)、移串(MOVS)
- 可以按照字節(jié)(B)、字(W)、雙字(D)進(jìn)行數(shù)據(jù)處理,
2. P53,62
扇區(qū)
一個(gè)扇區(qū)是512byte,setup 程序大約為 4 個(gè)扇區(qū)
段地址+偏移地址
- x86處理器地址總線是20位,而內(nèi)部數(shù)據(jù)總線、寄存器都是16位的。
- 如何用16位寄存器表示20位?物理地址=段地址 << 4 + 偏移地址
- eg
ss = 0x9000,sp=0xff00,那么sp指向的地址是0x90000 + 0xff00 = 0x9ff00
3. P53,67
INT 0x13 磁盤服務(wù)程序
-
功能號(hào)0x00, 復(fù)位驅(qū)動(dòng)器
AH = 0X00,DL = 需要復(fù)位的驅(qū)動(dòng)器號(hào)。
-
功能號(hào)0x02, 讀磁盤扇區(qū)到內(nèi)存
AH = 0x02,AL = 需要讀出的扇區(qū)數(shù)量;
CH = 磁道(柱面)號(hào)的低 8 位; CL = 開始扇區(qū)(0-5 位),磁道號(hào)高 2 位(6-7);
DH = 磁頭號(hào); DL = 驅(qū)動(dòng)器號(hào)(如果是硬盤則位 7 要置位);
es:bx 指向數(shù)據(jù)緩沖區(qū); 如果讀取失敗則 CF 標(biāo)志置位返回信息
傳輸成功:CF=0,AH=00H,AL=傳輸?shù)纳葏^(qū)數(shù)
傳輸失敗:CF=1,AH=狀態(tài)代碼(見下表)
01H — 非法命令 | 02H — 地址目標(biāo)未發(fā)現(xiàn) | 03H — 磁盤寫保護(hù)(軟盤) | 05H — 復(fù)位失敗(硬盤) |
---|---|---|---|
06H — 軟盤取出(軟盤) | 07H — 錯(cuò)誤的參數(shù)表(硬盤) | 08H — DMA越界(軟盤) | 09H — DMA超過(guò)64K界限 |
0AH — 錯(cuò)誤的扇區(qū)標(biāo)志(硬盤) | 0BH — 錯(cuò)誤的磁道標(biāo)志(硬盤) | 0CH — 介質(zhì)類型未發(fā)現(xiàn)(軟盤) | 0DH — 格式化時(shí)非法扇區(qū)號(hào)(硬盤) |
0EH — 控制數(shù)據(jù)地址目標(biāo)被發(fā)現(xiàn)(硬盤) | 0FH — DMA仲裁越界(硬盤) | 10H — 不正確的CRC或ECC編碼 | 11H — ECC校正數(shù)據(jù)錯(cuò)(硬盤) |
20H — 控制器失敗 | 40H — 查找失敗 | 80H — 磁盤超時(shí)(未響應(yīng)) | AAH — 驅(qū)動(dòng)器未準(zhǔn)備好(硬盤) |
BBH — 未定義的錯(cuò)誤(硬盤) | CCH — 寫錯(cuò)誤(硬盤) | E0H — 狀態(tài)寄存器錯(cuò)(硬盤) | FFH — 檢測(cè)操作失敗(硬盤) |
-
功能號(hào)0x08,讀取磁盤驅(qū)動(dòng)器參數(shù)
AH = 0x08,DL = 驅(qū)動(dòng)器號(hào)(如果是硬盤則要置位 7 為 1)
返回信息如果出錯(cuò)則 CF 置位,并且 AH = 狀態(tài)碼。
AH = 0, AL = 0
BL = 驅(qū)動(dòng)器類型(AT/PS2)
CH = 最大磁道號(hào)的低 8 位,CL = 每磁道最大扇區(qū)數(shù)(位 0-5),最大磁道號(hào)高 2 位(位 6-7)
DH = 最大磁頭數(shù),DL = 驅(qū)動(dòng)器數(shù)量
es:di 軟驅(qū)磁盤參數(shù)表
4. P54,92~102
INT 0x10
由 BIOS 對(duì)屏幕及顯示器所提供的服務(wù)程序
! Print some inane message
mov ah, #0x03 ! read cursor pos,AH=0x03,讀取光標(biāo),為了獲取光標(biāo)當(dāng)前的行列
xor bh, bh !bh = 頁(yè)號(hào)
int 0x10
mov cx, #24
mov bx, #0x0007 ! page 0, attribute 7 (normal)
mov bp, #msg1
mov ax, #0x1301 ! write string, move cursor
int 0x10
讀取光標(biāo)是必要的,為了獲取光標(biāo)位置(DH、DL)
-
AH=3,讀光標(biāo)位置
BH = 頁(yè)號(hào)
CH = 光標(biāo)開始行
CL = 光標(biāo)結(jié)束行
DH = 行
DL = 列 -
AH=13,表示顯示字符串
ES:BP = 串地址
CX = 串長(zhǎng)度
DH, DL = 起始行列
BH = 頁(yè)號(hào)
BL = 07H,正常的黑底白字
P55,151~155
read_it:
mov ax, es
test ax, #0x0fff
die: jne die ! es must be at 64kB boundary
xor bx, bx ! bx is starting address within segment
test指令
- test的解釋( Intel技術(shù)手冊(cè))
TEMP ← SRC1 AND SRC2 ;
SF ← MSB(TEMP) ;
IF TEMP = 0
THEN ZF ← 1 ;
ELSE ZF ← 0 ;
FI:
PF ← BitwiseXNOR(TEMP[0:7]);
CF ← 0 ;
OF ← 0 ;
- 對(duì)代碼的解釋
- test是進(jìn)行位與操作,相與等于0,說(shuō)明ax=es=0x1000,ZF=1
- JNE/JNZ都是ZF標(biāo)志位為0時(shí)跳轉(zhuǎn),如果es在64kb處,則順序執(zhí)行;否則,死鎖
子程序151~218
實(shí)現(xiàn)功能
該子程序?qū)⑾到y(tǒng)模塊加載到內(nèi)存地址 0x10000 處,并確定沒有跨越 64KB 的內(nèi)存邊界。我們?cè)噲D盡快 地進(jìn)行加載,只要可能,就每次加載整條磁道的數(shù)據(jù)
執(zhí)行流程
-
read_it
- 檢測(cè)讀入的數(shù)據(jù)是否在內(nèi)存地址64kB處
- 是,則執(zhí)行rp_read;否,則死鎖
-
rp_read
- 首先判斷是否已經(jīng)讀完
- 是,返回調(diào)用處;否,執(zhí)行ok1_read
-
ok1_read
- 取當(dāng)前磁道的扇區(qū)數(shù),計(jì)算是否超過(guò)64kB
- 是,計(jì)算能讀取的最大值;否,執(zhí)行ok2_read
-
ok2_read
- 執(zhí)行讀取操作(跳轉(zhuǎn)到了read_track)
- 傳輸?shù)纳葏^(qū)數(shù)存儲(chǔ)在AL中,判斷是否已經(jīng)讀完當(dāng)前磁道的所有扇區(qū)
- 是,順序執(zhí)行,如果當(dāng)前磁道是0,則磁道號(hào)+1,執(zhí)行ok4_read;如果磁道號(hào)是1,則直接跳轉(zhuǎn)到ok4_read;否,執(zhí)行ok3_read
-
ok3_read
- 計(jì)算當(dāng)前已讀扇區(qū)數(shù)量,將讀取位置存儲(chǔ)在bx中
- 跳轉(zhuǎn)到rp_read,繼續(xù)讀取
-
ok4_read
- 保存磁道號(hào),清空ax
- 如果未讀完,進(jìn)入ok3_read;否則,調(diào)整基址跳轉(zhuǎn)到rp_read
-
read_track
- 對(duì)通用 寄存器壓棧保護(hù)
- 設(shè)置要讀取的驅(qū)動(dòng)器號(hào)、磁道號(hào)、扇區(qū),然后調(diào)用INT 0x13軟件中斷
- 調(diào)用正確,返回調(diào)用處;否則,執(zhí)行bad_rt,驅(qū)動(dòng)器復(fù)位,然后重新跳轉(zhuǎn)執(zhí)行read_track
-
kill_motor
關(guān)閉軟驅(qū)的馬達(dá),這樣我們進(jìn)入內(nèi)核后它處于已知狀態(tài),以后也就無(wú)須擔(dān)心它了
子程序執(zhí)行流圖
8086寄存器
數(shù)據(jù)寄存器
- AX (Accumulator):累加寄存器,也稱之為累加器;
- BX (Base):基地址寄存器;
- CX (Count):計(jì)數(shù)器寄存器;
- DX (Data):數(shù)據(jù)寄存器;
指針寄存器
- SP (Stack Pointer):堆棧指針寄存器;
- BP (Base Pointer):基指針寄存器;
變址寄存器
- SI (Source Index):源變址寄存器
- DI (Destination Index):目的變址寄存器;
控制寄存器
- IP (Instruction Pointer):指令指針寄存器;
- FLAG:標(biāo)志寄存器;
段寄存器:
- CS (Code Segment):代碼段寄存器;
- DS (Data Segment):數(shù)據(jù)段寄存器;
- SS (Stack Segment):堆棧段寄存器;
- ES (Extra Segment):附加段寄存器