国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
FAT12文件格式
F AT12是DOS時(shí)代就開始使用的文件系統(tǒng)(File System),直到現(xiàn)在仍然在軟盤上使用。幾乎所有的文件系統(tǒng)都會(huì)把磁盤劃分為若干層次以方便管理和組織,這些層次主要包括:
扇區(qū)(Sector):磁盤上的最小數(shù)據(jù)單元
簇(Cluster):一個(gè)或多個(gè)扇區(qū)
分區(qū)(Partition):通常是指整個(gè)文件系統(tǒng)
下面是FAT12格式的軟盤存儲(chǔ)圖:
FAT12引導(dǎo)扇區(qū)的格式
名稱偏移長度內(nèi)容示例值
BS_jmpBoot03一個(gè)跳轉(zhuǎn)指令
jmp LABEL_START
nop
BS_OEMNane38廠商名'ForrestY'
BPB_BytePerSec112每扇區(qū)字節(jié)數(shù)0x200
BPB_SecPerClus131每簇扇區(qū)數(shù)0x1
BPB_RsvdSecCnt142Boot記錄占用多少扇區(qū)0x1
BPB_NumFATs161共有多少FAT表0x2
BPB_RootEntCnt172根目錄文件數(shù)最大值0xE0
BPB_TotSec16192扇區(qū)總數(shù)0xB40
BPB_Media211介質(zhì)描述符0xF0
BPB_FATSz16222每FAT扇區(qū)數(shù)0x9
BPB_SecPerTrk242每磁道扇區(qū)數(shù)0x12
BPB_Numheads262磁頭數(shù)(面數(shù))0x2
BPB_HiddSec284隱藏扇區(qū)數(shù)0
BPB_TotSec32324如果BPB_TotSec16是0,由這個(gè)值記錄扇區(qū)數(shù)0
BS_DrvNum361中斷13的驅(qū)動(dòng)器號(hào)0
BS_Reserved1371未使用0
BS_BootSig381擴(kuò)展引用標(biāo)記(29h)0x29
BS_VolID394卷序列號(hào)0
BS_VolLab4311卷標(biāo)'OrangesS0.02'
BS_FileSysType548文件系統(tǒng)類型'FAT12'
引導(dǎo)代碼及其他62448引導(dǎo)代碼、數(shù)據(jù)及其他填充字符等引導(dǎo)代碼(其余為0)
結(jié)束標(biāo)志51020xAA550xAA55
FAT表
FAT表占1-18扇區(qū),共兩個(gè)FAT表,F(xiàn)AT1和FAT2,一般FAT2不用,F(xiàn)AT2僅是FAT1的拷貝,每個(gè)FAT表占9個(gè)分區(qū),即 (512*9=4608)字節(jié),F(xiàn)AT表由FAT項(xiàng)組成,每個(gè)FAT項(xiàng)占12位,共3072個(gè)FAT項(xiàng),去掉兩個(gè)不用的FAT的項(xiàng)(0和1,這是因?yàn)閿?shù)據(jù)區(qū)的簇號(hào)是從2開始的0和1不用,故對(duì)應(yīng)的FAT表中的0和1也不用),故FAT12功能管理3070個(gè)簇區(qū)即 (1.499M*BPB_SecPerClus,這里是1.499M)的大小。
要注意的是,由于每個(gè)FAT項(xiàng)占12位,包含一個(gè)字節(jié)和另一個(gè)字節(jié)的一半。如上圖所示連續(xù)的3個(gè)字節(jié)表示兩個(gè)FAT項(xiàng),BYTE1是Fat Entry1的低8位,BYTE2的低4位是Fat Entry1的高4位,BYTE2的高4位是Fat Entry2的低4位,BYTE3是Fat Entry2的高8位。
下面介紹根目錄:
僅跟FAT表的是根目錄,從第19個(gè)分區(qū)開始,它是由若干個(gè)目錄條目(Directory Entry)組成,條目最多有BPB_RootEntCnt個(gè)。由于根目錄區(qū)的大小依賴于BPB_RootEntCnt的大小,所以長度不固定。
根目錄中的每一個(gè)條目占用32字節(jié),它的格式如下表所示:
名稱 開始字節(jié) 長度 內(nèi)容
DIR_Name 0 0xB 文件名8字節(jié),擴(kuò)展名3字節(jié)
DIR_Attr 0xB 1 文件屬性
保留位 0xC 10 保留
DIR_WrtTime 0x16 2 最后一次寫入的時(shí)間
DIR_WrtDate 0x18 2 最后一次寫入的日期
DIR_FstClus 0x1A 2 此文件在數(shù)據(jù)區(qū)和FAT表中的開始簇號(hào)
DIR_FileSize 0x1C 4 文件大小
數(shù)據(jù)區(qū)
需要注意的是數(shù)據(jù)區(qū)的第一個(gè)簇號(hào)是2,而不是0或者1,(簇號(hào)和扇區(qū)號(hào)在這里是一樣的,因?yàn)橐淮刂挥幸粋€(gè)扇區(qū)),假設(shè)根目錄區(qū)共占有RootDirSectors個(gè)扇區(qū),則有:
RootDirSectors =[ (BPB_RootEntCnt*32)+(BPB_BytesPerSec-1)]/BPB_BytsPerSec
只所以分子上要加上(BPB_BytesPerSec-1),是為了保證此公式在根目錄區(qū)無法填滿整數(shù)個(gè)扇區(qū)時(shí)仍然成立。
DOS可以識(shí)別的引導(dǎo)盤
Nasm代碼
 
;===============================================================================
jmp short LABEL_START
nop                 ;必不可少的
;**以下是FAT12的磁盤頭的定義************
BS_OEMName  DB 'SongYang'       ;OEM String, 必須 8 個(gè)字節(jié)
BSB_BytePerSec  DW 512          ;每扇區(qū)字節(jié)數(shù)
BSP_SecPerClus  Db 1            ;每簇多少扇區(qū)
BPB_RsvdSecCnt  DW 1            ;Boot 記錄占用多少扇區(qū)
BSP_NumFats DB 2            ;共有多少 FAT 表
BSP_RootEntCnt  DW 224          ;根目錄文件數(shù)最大值
BSP_TotSec16    DW 2880         ;邏輯扇區(qū)總數(shù)
BPB_Media   DB 0xF0         ;媒體描述符
BPB_FATSz16 DW 9            ;每FAT扇區(qū)數(shù)
BPB_SecPerTrk   DW 18           ;每磁道扇區(qū)數(shù)
BPB_NumHeads    DW 2            ;磁頭數(shù)(面數(shù))
BPB_HiddSec DD 0            ;隱藏扇區(qū)數(shù)
BPB_TotSec32    DD 0            ;如果 wTotalSectorCount 是0由這個(gè)值記錄
;扇區(qū)數(shù)
BS_DrvNum   DB 0            ;中斷 13 的驅(qū)動(dòng)器號(hào)
BS_Reserved1    DB 0            ;未使用
BS_BootSig  DB 29h          ;擴(kuò)展引導(dǎo)標(biāo)記 (29h)
BS_VolID    DD 0            ;卷序列號(hào)
BS_Volab    DB 'Tinix0.01  '    ;卷標(biāo), 必須 11 個(gè)字節(jié)
BS_FileSysType  DB 'FAT12   '       ;文件系統(tǒng)類型, 必須 8個(gè)字節(jié)
LABEL_START:
軟盤的讀寫
要讀寫軟盤的話,這時(shí)就需要BIOS中斷int 13h。用法如下:
中斷號(hào) 寄存器 作用
13h
ah=00h
dl=驅(qū)動(dòng)器號(hào)(0表示A盤) 復(fù)位軟驅(qū)
ah=02h
ch=柱面(磁道)號(hào)
dh=磁頭號(hào)
es:bx->數(shù)據(jù)緩沖區(qū)
al=要讀扇區(qū)數(shù)
cl=起始扇區(qū)號(hào)
dl=驅(qū)動(dòng)器號(hào)(0表示A盤) 從磁盤讀數(shù)據(jù)入es:bx
指向的緩沖區(qū)
下面我們編寫一個(gè)示例,按上述 FAT12引導(dǎo)扇區(qū)的格式 編寫一個(gè)引導(dǎo)程序讀出FAT12軟盤中的一個(gè)文件(test.txt)并將其打印在屏幕上,然后將編寫的引導(dǎo)程序?qū)懭胍龑?dǎo)扇區(qū)即0號(hào)扇區(qū),這樣軟盤的文件格式就是FAT12了,這時(shí)就可以在
DOS或者其他操作系統(tǒng)下訪問軟盤了,向里面新建一個(gè)文件test.txt并些入一些什么,然后將其作為啟動(dòng)盤啟動(dòng),就會(huì)自動(dòng)運(yùn)行引導(dǎo)程序,找到文件test.txt并打印出文件中的東西。下面介紹具體的做法:
1.扇區(qū)的讀寫
從上表中 我們發(fā)現(xiàn)int 13h的參數(shù)不是扇區(qū)號(hào) ,而是用磁頭號(hào)、柱面和起始扇區(qū)表示的,那我們?nèi)绾沃郎葏^(qū)號(hào)來讀取扇區(qū)呢,首先進(jìn)行轉(zhuǎn)換,公式如下:
扇區(qū)號(hào)/每磁道扇區(qū)數(shù)(BPB_SecPerTrk,18) 商Q=>柱面號(hào)=Q>>1
磁頭號(hào)=Q&1
余數(shù)R=> 起起始扇區(qū)號(hào)=R+1
下面我們實(shí)現(xiàn)一個(gè)函數(shù)來讀取扇區(qū)ReadSector():
參數(shù):
ax從第axSector開始讀
cl讀取cl個(gè)Sector
es:bx讀到緩沖區(qū)es:bx
代碼如下:
Nasm代碼
 
;----------------------------------------------------------------------------
; 函數(shù)名: ReadSector
;----------------------------------------------------------------------------
; 作用:
;   從第 ax 個(gè) Sector 開始, 將 cl 個(gè) Sector 讀入 es:bx 中
ReadSector:
; -----------------------------------------------------------------------
; 怎樣由扇區(qū)號(hào)求扇區(qū)在磁盤中的位置 (扇區(qū)號(hào) -> 柱面號(hào), 起始扇區(qū), 磁頭號(hào))
; -----------------------------------------------------------------------
; 設(shè)扇區(qū)號(hào)為 x
;                           ┌ 柱面號(hào) = y >> 1
;       x           ┌ 商 y ┤
; -------------- => ┤      └ 磁頭號(hào) = y & 1
;  每磁道扇區(qū)數(shù)     │
;                   └ 余 z => 起始扇區(qū)號(hào) = z + 1
push    bp
mov bp, sp
sub esp, 2          ; 辟出兩個(gè)字節(jié)的堆棧區(qū)域保存要讀的扇區(qū)數(shù): byte
[bp-2]
mov byte [bp-2], cl
push    bx          ; 保存 bx
mov bl, [BPB_SecPerTrk] ; bl: 除數(shù)
div bl          ; y 在 al 中, z 在 ah 中
inc ah          ; z ++
mov cl, ah          ; cl <- 起始扇區(qū)號(hào)
mov dh, al          ; dh <- y
shr al, 1           ; y >> 1 (其實(shí)是 y/BPB_NumHeads, 這里
BPB_NumHeads=2)
mov ch, al          ; ch <- 柱面號(hào)
and dh, 1           ; dh & 1 = 磁頭號(hào)
pop bx          ; 恢復(fù) bx
; 至此, "柱面號(hào), 起始扇區(qū), 磁頭號(hào)" 全部得到 ^^
mov dl, [BS_DrvNum]     ; 驅(qū)動(dòng)器號(hào) (0 表示 A 盤)
.GoOnReading:
mov ah, 2           ; 讀
mov al, byte [bp-2]     ; 讀 al 個(gè)扇區(qū)
int 13h
jc  .GoOnReading        ; 如果讀取錯(cuò)誤 CF 會(huì)被置為 1, 這時(shí)就不停地讀, 直到
正確為止
add esp, 2
pop bp
ret
注意事項(xiàng):
注意各個(gè)參數(shù)的取值范圍的問題,并不是隨意取值的;每次讀取扇區(qū)只能在同一個(gè)磁道中讀取,也就是說一次最多能讀取BPB_SecPerTrk(18)個(gè)扇區(qū),也就是說cl的取值小于等于[BPB_SecPerTrk-(ax%BPB_SecPerTrk)].
es:bx的選擇問題,如果es:bx 和 cl選取的不當(dāng) 會(huì)出現(xiàn)【09h = DMA across 64K boundary】這個(gè)錯(cuò)誤,原因不知道,有知道的可以告訴我。
舉個(gè)例子:讀取9個(gè)扇區(qū)到8EE0:0000h不出錯(cuò),但是讀到8EE0:0001h就出錯(cuò)!但是讀取8個(gè)以下的扇區(qū)則沒問題!很奇怪的問題。以下是我的猜測:
DMA的緩存是64k的大小,8000:0000h-9000:0000h正好是64K,也就是內(nèi)存按64K劃分,DMA緩沖區(qū)對(duì)應(yīng)于每個(gè)64K的內(nèi)存,而8EE0:0000h-9000:0000h正好是9個(gè)扇區(qū)的大小,8EE0:0001h則少了一個(gè)字節(jié),故出錯(cuò)!這只是本人的猜測,查了很長時(shí)間也沒差到原因,有知道的可以告訴我。
2.獲得文件的第一個(gè)簇號(hào)(這里也是區(qū)號(hào),二則相等)
要想獲某個(gè)文件的第一個(gè)簇號(hào) 需要在根目錄中查找對(duì)應(yīng)的目錄項(xiàng)(這里假設(shè)文件都放在了根目錄中個(gè)),步驟如下:
將整個(gè)根目錄區(qū)域加載進(jìn)內(nèi)存,(根目錄不是很大,相對(duì)現(xiàn)在的大內(nèi)存),直接加載進(jìn)內(nèi)存方便操作。
Nasm代碼
 
;**將根目錄整個(gè)的都讀到es:bx處
mov ax, BaseOfLoader
mov es, ax          ; es <- BaseOfLoader
mov bx, OffsetOfLoader  ; bx <- OffsetOfLoader   于是, es:bx =
BaseOfLoader:OffsetOfLoader
mov ax, SectorNoOfRootDirectory ; ax <- Root Directory 中的某 Sector 號(hào)
mov cl, RootDirSectors      ;將根目錄都讀出來
call    ReadSector
在根目錄中逐條查找直到結(jié)束,代碼如下:
這里得到的簇號(hào)就是區(qū)號(hào)SecNo,因?yàn)檫@里一個(gè)簇里面只有一個(gè)扇區(qū),但是數(shù)據(jù)區(qū)的第一個(gè)簇號(hào)是從2開始的,要計(jì)算其對(duì)應(yīng)的扇區(qū)號(hào)應(yīng)按下面的公式計(jì)算:
SecNo = SecNo + (1+9*2 +RootDirSectors -2 -1)
其1個(gè)引導(dǎo)扇區(qū),2個(gè)FAT表,0個(gè)隱藏扇區(qū),RootDirSectors個(gè)根目錄,由于第一個(gè)簇號(hào)事2故要減去2,編號(hào)是從0開始的故要減去個(gè)1。
Nasm代碼
 
mov si, LoaderFileName  ; ds:si -> "TEST    TXT"
mov di, OffsetOfLoader  ; es:di -> BaseOfLoader:0100 =
BaseOfLoader*10h+100
cld             ;設(shè)置方向標(biāo)志
mov cx, [BSP_RootEntCnt]
mov [RootDirectItemNum], cx ;根目錄的條數(shù)
LABEL_SEARCH_FOR_LOADERBIN:
cmp word [RootDirectItemNum], 0
jz NOLOADER
dec word [RootDirectItemNum]
mov cx, 11
LABEL_CMP_FILENAME:
cmp cx, 0
jz  LABEL_FILENAME_FOUND    ; 如果比較了 11 個(gè)字符都相等, 表示找到
dec cx
lodsb               ; ds:si -> al
cmp al, byte [es:di]
jz  LABEL_GO_ON
jmp LABEL_DIFFERENT     ; 只要發(fā)現(xiàn)不一樣的字符就表明本 DirectoryEntry 不是
LABEL_GO_ON:
inc di
jmp LABEL_CMP_FILENAME
LABEL_DIFFERENT:
and di, 0FFE0h
add di, 020h
and si, LoaderFileName
jmp LABEL_SEARCH_FOR_LOADERBIN
NOLOADER:
mov dh, 0
call DispStr
jmp $
LABEL_FILENAME_FOUND:
and di, 0FFE0h
mov eax, [es:di+0x1C]
mov [FileLength], eax
add di, 01Ah        ; di -> 首 Sector(偏移)
mov cx, word [es:di]
push cx         ;cx里面放的是Loader的第一個(gè)扇區(qū)號(hào)(數(shù)據(jù)區(qū)的從2開始)
3.FAT表中的下一個(gè)簇號(hào)
同樣的道理先將整個(gè)FAT表讀到內(nèi)存中:
Nasm代碼
 
;**讀取Fat表
mov ax, BaseOfLoader
sub ax, FatOffset   ;分配5k內(nèi)存(512*10/1024)
mov es, ax
mov bx, 0       ;將Fat讀到es:bx
mov ax, [BPB_RsvdSecCnt];Fat開始扇區(qū) 1
mov cl, [BPB_FATSz16]
call ReadSector
然后查找下一個(gè)簇號(hào),由于可能多次調(diào)用寫成了一個(gè)函數(shù)GetFATEntry():
參數(shù)ax:簇號(hào)
返回值ax:下一個(gè)簇號(hào),需要注意簇號(hào)大于等于0xFF8表示文件的最后一個(gè)簇,為0xFF7表示壞簇。
Nasm代碼
 
;----------------------------------------------------------------------------
; 函數(shù)名: GetFATEntry
;----------------------------------------------------------------------------
; 作用: ax
;
GetFATEntry:
push bp
mov bp, sp
sub esp, 2
mov word [bp-2], 0
push es
push bx
push dx
mov bx, 3
mul bx              ;ax = ax * 3
mov bx, 2
div bx              ;商在ax 余數(shù)在dx
cmp dx, 0
jz LABEL_EVEN           ;偶數(shù)
mov word [bp-2], 1      ;奇數(shù)
LABEL_EVEN:
mov bx, ax
mov ax, BaseOfLoader
sub ax, FatOffset
mov es, ax
mov word ax, [es:bx]
cmp word [bp-2], 0
jz LABEL_EVEN_2
shr ax, 4
LABEL_EVEN_2:
and ax, 0FFFh           ;低十二位
pop dx
pop bx
pop es
add esp, 2
pop bp
ret
最后給出整個(gè)的程序:
Nasm代碼
 
;*******************************************************************************80
;**boot.asm 軟盤引導(dǎo)分區(qū)
;*******************************************************************************
org 07c00h              ;BIOS將把Boot Sector開機(jī)加載到
;地址0000:7c00 并執(zhí)行
;==宏===========================================================================
BaseOfStack equ 07c00h      ;boot狀態(tài)下的堆?;刂?注意堆棧是向下
;生長的)
;Loader address
BaseOfLoader        equ  09000h ;TEST.TXT 被加載到的位置 ----  段地址
OffsetOfLoader      equ   0100h ;TEST.TXT 被加載到的位置 ---- 偏移地
;址 (共63K的大小)
;FAT12
SectorNoOfRootDirectory equ 19  ;Root Directory 的第一個(gè)扇區(qū)號(hào)=
;BPB_RsvdSecCnt + (BPB_NumFATs * FATSz)
RootDirSectors      equ 14  ; 根目錄占用空間: RootDirSectors =
;((BPB_RootEntCnt * 32) + (BPB_BytsPerSec
; – 1)) / BPB_BytsPerSec; 但如果按照此公
;式代碼過長
FatOffset       equ     120h    ;FAT表緩沖偏移
;===============================================================================
jmp short LABEL_START
nop                 ;必不可少的
;**以下是FAT12的磁盤頭的定義************
BS_OEMName  DB 'SongYang'       ;OEM String, 必須 8 個(gè)字節(jié)
BSB_BytePerSec  DW 512          ;每扇區(qū)字節(jié)數(shù)
BSP_SecPerClus  Db 1            ;每簇多少扇區(qū)
BPB_RsvdSecCnt  DW 1            ;Boot 記錄占用多少扇區(qū)
BSP_NumFats DB 2            ;共有多少 FAT 表
BSP_RootEntCnt  DW 224          ;根目錄文件數(shù)最大值
BSP_TotSec16    DW 2880         ;邏輯扇區(qū)總數(shù)
BPB_Media   DB 0xF0         ;媒體描述符
BPB_FATSz16 DW 9            ;每FAT扇區(qū)數(shù)
BPB_SecPerTrk   DW 18           ;每磁道扇區(qū)數(shù)
BPB_NumHeads    DW 2            ;磁頭數(shù)(面數(shù))
BPB_HiddSec DD 0            ;隱藏扇區(qū)數(shù)
BPB_TotSec32    DD 0            ;如果 wTotalSectorCount 是0由這個(gè)值記錄
;扇區(qū)數(shù)
BS_DrvNum   DB 0            ;中斷 13 的驅(qū)動(dòng)器號(hào)
BS_Reserved1    DB 0            ;未使用
BS_BootSig  DB 29h          ;擴(kuò)展引導(dǎo)標(biāo)記 (29h)
BS_VolID    DD 0            ;卷序列號(hào)
BS_Volab    DB 'Tinix0.01  '    ;卷標(biāo), 必須 11 個(gè)字節(jié)
BS_FileSysType  DB 'FAT12   '       ;文件系統(tǒng)類型, 必須 8個(gè)字節(jié)
LABEL_START:
;**初始化寄存器*************************
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, BaseOfStack
;**清屏*********************************
mov ax, 0600h       ; AH = 6,  AL = 0h
mov bx, 0700h       ; 黑底白字(BL = 07h)
mov cx, 0           ; 左上角: (0, 0)
mov dx, 0184fh      ; 右下角: (80, 50)
int 10h         ; int 10h
;**軟驅(qū)復(fù)位*****************************
xor ah, ah  ; ┓
xor dl, dl  ; ┣ 軟驅(qū)復(fù)位
int 13h     ; ┛
;**在軟盤中尋找Loader.bin(FAT12)********
;**將根目錄整個(gè)的都讀到es:bx處
mov ax, BaseOfLoader
mov es, ax          ; es <- BaseOfLoader
mov bx, OffsetOfLoader  ; bx <- OffsetOfLoader   于是, es:bx =
BaseOfLoader:OffsetOfLoader
mov ax, SectorNoOfRootDirectory ; ax <- Root Directory 中的某 Sector 號(hào)
mov cl, RootDirSectors      ;將根目錄都讀出來
call    ReadSector
;mov    ax, BaseOfLoader
;mov    es, ax
;mov    ax, cs
;mov    ds, ax
mov si, LoaderFileName  ; ds:si -> "TEST    TXT"
mov di, OffsetOfLoader  ; es:di -> BaseOfLoader:0100 =
BaseOfLoader*10h+100
cld             ;設(shè)置方向標(biāo)志
mov cx, [BSP_RootEntCnt]
mov [RootDirectItemNum], cx ;根目錄的條數(shù)
LABEL_SEARCH_FOR_LOADERBIN:
cmp word [RootDirectItemNum], 0
jz NOLOADER
dec word [RootDirectItemNum]
mov cx, 11
LABEL_CMP_FILENAME:
cmp cx, 0
jz  LABEL_FILENAME_FOUND    ; 如果比較了 11 個(gè)字符都相等, 表示找到
dec cx
lodsb               ; ds:si -> al
cmp al, byte [es:di]
jz  LABEL_GO_ON
jmp LABEL_DIFFERENT     ; 只要發(fā)現(xiàn)不一樣的字符就表明本 DirectoryEntry 不是
LABEL_GO_ON:
inc di
jmp LABEL_CMP_FILENAME
LABEL_DIFFERENT:
and di, 0FFE0h
add di, 020h
and si, LoaderFileName
jmp LABEL_SEARCH_FOR_LOADERBIN
NOLOADER:
mov dh, 0
call DispStr
jmp $
LABEL_FILENAME_FOUND:
and di, 0FFE0h
mov eax, [es:di+0x1C]
mov [FileLength], eax
add di, 01Ah        ; di -> 首 Sector(偏移)
mov cx, word [es:di]
push cx         ;cx里面放的是Loader的第一個(gè)扇區(qū)號(hào)(數(shù)據(jù)區(qū)的從2開始)
;******************************
;**讀取Fat表
mov ax, BaseOfLoader
sub ax, FatOffset   ;分配5k內(nèi)存(512*10/1024)
mov es, ax
mov bx, 0       ;將Fat讀到es:bx
mov ax, [BPB_RsvdSecCnt];Fat開始扇區(qū) 1
mov cl, [BPB_FATSz16]
call ReadSector
;**讀取Loader到內(nèi)存*******
mov ax, BaseOfLoader
mov es, ax
mov bx, OffsetOfLoader
pop ax
LABEL_GOON_LOADING_FILE:
push    ax      ;保存ax
add     ax, 17 + 14
mov     cl, 1   ;一個(gè)扇區(qū)
call    ReadSector
;
pop     ax      ;回復(fù)ax
call    GetFATEntry;獲得下個(gè)號(hào)碼
cmp     ax, 0FFFh
jz  LABEL_FILE_LOADED
add     bx, [BSB_BytePerSec]
jmp     LABEL_GOON_LOADING_FILE
LABEL_FILE_LOADED:
;打印文件內(nèi)容
mov ax, BaseOfLoader
mov es, ax
mov bp, OffsetOfLoader
mov cx, [FileLength]    ; CX = 串長度
mov ax, 01301h      ; AH = 13,  AL = 01h
mov bx, 0006h       ; 頁號(hào)為0(BH = 0) 黑底白字(BL = 07h)
mov dl, 0
mov     dh, 0
int 10h         ; int 10h
jmp $
;============================================================================
;字符串
;----------------------------------------------------------------------------
LoaderFileName      db  "TEST    TXT", 0    ; LOADER.BIN 之文件名
RootDirectItemNum   DW  0
FileLength      DW  0
; 為簡化代碼, 下面每個(gè)字符串的長度均為 MessageLength
MessageLength       equ 9
BootMessage:        db "No FILE  "      ; 7字節(jié)
;============================================================================
;----------------------------------------------------------------------------
; 函數(shù)名: DispStr
;----------------------------------------------------------------------------
; 作用:
;   顯示一個(gè)字符串, 函數(shù)開始時(shí) dh 中應(yīng)該是字符串序號(hào)(0-based)
DispStr:
push ax
push bx
push cx
push dx
push es
mov ax, MessageLength
mul dh
add ax, BootMessage
mov bp, ax          ; ┓
mov ax, ds          ; ┣ ES:BP = 串地址
mov es, ax          ; ┛
mov cx, MessageLength   ; CX = 串長度
mov ax, 01301h      ; AH = 13,  AL = 01h
mov bx, 0006h       ; 頁號(hào)為0(BH = 0) 黑底白字(BL = 07h)
mov dl, 0
int 10h         ; int 10h
pop es
pop dx
pop cx
pop bx
pop ax
ret
;----------------------------------------------------------------------------
; 函數(shù)名: ReadSector
;----------------------------------------------------------------------------
; 作用:
;   從第 ax 個(gè) Sector 開始, 將 cl 個(gè) Sector 讀入 es:bx 中
ReadSector:
; -----------------------------------------------------------------------
; 怎樣由扇區(qū)號(hào)求扇區(qū)在磁盤中的位置 (扇區(qū)號(hào) -> 柱面號(hào), 起始扇區(qū), 磁頭號(hào))
; -----------------------------------------------------------------------
; 設(shè)扇區(qū)號(hào)為 x
;                           ┌ 柱面號(hào) = y >> 1
;       x           ┌ 商 y ┤
; -------------- => ┤      └ 磁頭號(hào) = y & 1
;  每磁道扇區(qū)數(shù)     │
;                   └ 余 z => 起始扇區(qū)號(hào) = z + 1
push    bp
mov bp, sp
sub esp, 2          ; 辟出兩個(gè)字節(jié)的堆棧區(qū)域保存要讀的扇區(qū)數(shù): byte
[bp-2]
mov byte [bp-2], cl
push    bx          ; 保存 bx
mov bl, [BPB_SecPerTrk] ; bl: 除數(shù)
div bl          ; y 在 al 中, z 在 ah 中
inc ah          ; z ++
mov cl, ah          ; cl <- 起始扇區(qū)號(hào)
mov dh, al          ; dh <- y
shr al, 1           ; y >> 1 (其實(shí)是 y/BPB_NumHeads, 這里
BPB_NumHeads=2)
mov ch, al          ; ch <- 柱面號(hào)
and dh, 1           ; dh & 1 = 磁頭號(hào)
pop bx          ; 恢復(fù) bx
; 至此, "柱面號(hào), 起始扇區(qū), 磁頭號(hào)" 全部得到 ^^^^^^^^^^^^^^^^^^^^^^^^
mov dl, [BS_DrvNum]     ; 驅(qū)動(dòng)器號(hào) (0 表示 A 盤)
.GoOnReading:
mov ah, 2           ; 讀
mov al, byte [bp-2]     ; 讀 al 個(gè)扇區(qū)
int 13h
jc  .GoOnReading        ; 如果讀取錯(cuò)誤 CF 會(huì)被置為 1, 這時(shí)就不停地讀, 直到
正確為止
add esp, 2
pop bp
ret
;----------------------------------------------------------------------------
; 函數(shù)名: GetFATEntry
;----------------------------------------------------------------------------
; 作用: ax
;
GetFATEntry:
push bp
mov bp, sp
sub esp, 2
mov word [bp-2], 0
push es
push bx
push dx
mov bx, 3
mul bx              ;ax = ax * 3
mov bx, 2
div bx              ;商在ax 余數(shù)在dx
cmp dx, 0
jz LABEL_EVEN           ;偶數(shù)
mov word [bp-2], 1      ;奇數(shù)
LABEL_EVEN:
mov bx, ax
mov ax, BaseOfLoader
sub ax, FatOffset
mov es, ax
mov word ax, [es:bx]
cmp word [bp-2], 0
jz LABEL_EVEN_2
shr ax, 4
LABEL_EVEN_2:
and ax, 0FFFh           ;低十二位
pop dx
pop bx
pop es
add esp, 2
pop bp
ret
times 510-($-$$) db 0           ;填充剩余的空間,是生成的代碼正好為512B
dw  0xaa55              ;結(jié)束標(biāo)記
編譯命令:
Java代碼
 
nasm -I .\include\ boot1.asm -o boot.bin
WriteFlopy.exe
WriteFlopy.exe的功能是見生成的boot.bin文件寫道虛擬軟盤TINIX.IMG的引導(dǎo)扇區(qū)中,然后可以將該虛擬軟盤掛載,向里面新建一個(gè)文件TEST.TXT然后寫一些東西測試。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
從頭開始編寫操作系統(tǒng)(7) 第6章:引導(dǎo)加載器4 - xiaoxiaoyaya的專欄 - ...
FAT32分區(qū)引導(dǎo)代碼
匯編語言--1. 備份引導(dǎo)區(qū)
NT,2000,XP 的 CDROM 引導(dǎo)扇區(qū)代碼分析
linux 0.11 內(nèi)核學(xué)習(xí)
學(xué)習(xí)x86匯編語言7 使用INT13讀取軟盤數(shù)據(jù)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服