亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

第四章boot.asm

系統 1941 0

跟上篇日志中間又隔了好幾天,懶惰啊

      
         1
      
      
        尋找LOADER.BIN文件的大體思路為:


      
      
         2
      
      
        LOADER.BIN文件存儲在A盤中,我們知道A盤的格式是FAT12格式,具體格式見書本P103,其主要是有引導扇區
      
      
         3
      
      
        、FAT1區、FAT2區、根目錄區(長度不固定,需要計算)和 數據區組成。引導扇區放的就是我們寫的引導代碼
      
      
         4
      
      
        boot.bin文件,我們的LOADER.BIN文件是放在數據區中的,而文件的文件名是放在根目錄中,因此,如果我
      
      
         5
      
      
        們想查看該盤是否含有我們想要的文件時,我們應該先到根目錄中查看是否含有該文件名,如果有,說明該盤存
      
      
         6
      
      
        在該文件,那么下面可以從盤中讀取該文件了。
      
      
         7
      
      
        文件在盤中是按照簇來進行存儲的,而在FAT12盤中,一個簇中只含有一個扇區,故下面我們只以扇區來進行說
      
      
         8
      
      
        明。所以文件在FAT12中是按照扇區(一個扇區512字節)來進行存儲的,所以一個文件一般會占多個扇區,而
      
      
         9
      
      
        每個文件占的扇區數會記錄在FAT1區中,我們只要從文件根目錄中獲取該文件在FAT1區中的起始地址,只要該
      
      
        10
      
      
        地址存儲的不是0xFFF說明該文件還占有其他扇區,我們繼續讀取該地址指向的扇區,直到FAT1項中的值為
      
      
        11
      
      
        0xFFF,這表示文件結束,讀取完畢.而根目錄也是按照扇區進行存儲的,所以我們得從根目錄起始扇區開始順
      
      
        12
      
      
        序讀取每個扇區,直到根目錄區結束。而每個根目錄項是32個字節,因此一個扇區可以有16個根目錄項,我們
      
      
        13 
      
      
        挨個比較每個根目錄項中的文件名和我們期望查找的文件名是否相同,如果相同就表示已經找到,只要取出根目錄項中的DIR_FstClus,然后從FAT1項中取出相應的數據即可。
      
      
        14
      
      
        如果沒有找到,那么就到下一個根目錄項中查找,如果當前扇區都沒有找到,那么讀取下一個扇區,直到這個根;目錄區結束。
      
    

?

尋找loader.bin的思路

1.首先要明白loader.bin文件的數據部分放在數據區,而關于文件大小,文件名等文件信息放在根目錄區

2.所以找文件的時候先到根目錄區找到文件名為loader.bin的文件信息,怎么找呢?我們知道,每個文件的信息在根目錄中占一項,每項為32字節,每個扇區共有16項;同時我們

還知道根目錄開始扇區位19,所以我們從該扇區開始讀取數據,每次讀一個扇區。在度過一個扇區以后,我們要分析這個扇區中的內容,具體是比較目錄項中文件名是否為

loader.bin,若是則在根目錄中文件查找完畢

3.在根目錄中找到loader.bin的信息之后,我們可以得到該文件在數據區的簇號(扇區號),同時也得到在fat表中的對應的項(index),p131小例子

4.反復根據步驟三得到信息讀完整個文件

      
          1
      
      
        ;
      
      
        %define    _BOOT_DEBUG_    ; 做 Boot Sector 時一定將此行注釋掉!將此行打開后用 nasm Boot.asm -o Boot.com 做成一個.COM文件易于調試
      
      
          2
      
      
          3
      
      
        %ifdef    _BOOT_DEBUG_


      
      
          4
      
           org  0100h            
      
        ;
      
      
         調試狀態, 做成 .COM 文件, 可調試
      
      
          5
      
      
        %else


      
      
          6
      
           org  07c00h            
      
        ;
      
      
         Boot 狀態, Bios 將把 Boot Sector 加載到 0:7C00 處并開始執行
      
      
          7
      
      
        %endif


      
      
          8
      
      
          9
      
      
        ;
      
      
        ================================================================================================
      
      
         10
      
      
        %ifdef    _BOOT_DEBUG_


      
      
         11
      
       BaseOfStack        equ    0100h    
      
        ;
      
      
         調試狀態下堆棧基地址(棧底, 從這個位置向低地址生長)
      
      
         12
      
      
        %else


      
      
         13
      
       BaseOfStack        equ    07c00h    
      
        ;
      
      
         Boot狀態下堆棧基地址(棧底, 從這個位置向低地址生長)
      
      
         14
      
      
        %endif


      
      
         15
      
      
         16
      
       BaseOfLoader        equ    09000h    
      
        ;
      
      
         LOADER.BIN 被加載到的位置 ----  段地址
      
      
         17
      
       OffsetOfLoader        equ    0100h    
      
        ;
      
      
         LOADER.BIN 被加載到的位置 ---- 偏移地址
      
      
         18
      
      
         19
      
       RootDirSectors        equ    
      
        14
      
      
        ;
      
      
         根目錄占用空間
      
      
         20
      
       SectorNoOfRootDirectory    equ    
      
        19
      
      
        ;
      
      
         Root Directory 的第一個扇區號
      
      
         21
      
       SectorNoOfFAT1        equ    
      
        1
      
      
        ;
      
      
         FAT1 的第一個扇區號    = BPB_RsvdSecCnt
      
      
         22
      
       DeltaSectorNo        equ    
      
        17
      
      
        ;
      
      
         DeltaSectorNo = BPB_RsvdSecCnt + (BPB_NumFATs * FATSz) - 2
      
      
         23
      
      
        ;
      
      
         文件的開始Sector號 = DirEntry中的開始Sector號 + 根目錄占用Sector數目 + DeltaSectorNo
      
      
         24
      
      
        ;
      
      
        ================================================================================================
      
      
         25
      
      
         26
      
      
        jmp
      
       short LABEL_START        
      
        ;
      
      
         Start to boot.
      
      
         27
      
      
        nop
      
      
        ;
      
      
         這個 nop 不可少
      
      
         28
      
      
         29
      
      
        ;
      
      
         下面是 FAT12 磁盤的頭
      
      
         30
      
           BS_OEMName    DB 
      
        '
      
      
        ForrestY
      
      
        '
      
      
        ;
      
      
         OEM String, 必須 8 個字節
      
      
         31
      
           BPB_BytsPerSec    DW 
      
        512
      
      
        ;
      
      
         每扇區字節數
      
      
         32
      
           BPB_SecPerClus    DB 
      
        1
      
      
        ;
      
      
         每簇多少扇區
      
      
         33
      
           BPB_RsvdSecCnt    DW 
      
        1
      
      
        ;
      
      
         Boot 記錄占用多少扇區
      
      
         34
      
           BPB_NumFATs    DB 
      
        2
      
      
        ;
      
      
         共有多少 FAT 表
      
      
         35
      
           BPB_RootEntCnt    DW 
      
        224
      
      
        ;
      
      
         根目錄文件數最大值
      
      
         36
      
           BPB_TotSec16    DW 
      
        2880
      
      
        ;
      
      
         邏輯扇區總數
      
      
         37
      
           BPB_Media    DB 0xF0        
      
        ;
      
      
         媒體描述符
      
      
         38
      
           BPB_FATSz16    DW 
      
        9
      
      
        ;
      
      
         每FAT扇區數
      
      
         39
      
           BPB_SecPerTrk    DW 
      
        18
      
      
        ;
      
      
         每磁道扇區數
      
      
         40
      
           BPB_NumHeads    DW 
      
        2
      
      
        ;
      
      
         磁頭數(面數)
      
      
         41
      
           BPB_HiddSec    DD 
      
        0
      
      
        ;
      
      
         隱藏扇區數
      
      
         42
      
           BPB_TotSec32    DD 
      
        0
      
      
        ;
      
      
         如果 wTotalSectorCount 是 0 由這個值記錄扇區數
      
      
         43
      
           BS_DrvNum    DB 
      
        0
      
      
        ;
      
      
         中斷 13 的驅動器號
      
      
         44
      
           BS_Reserved1    DB 
      
        0
      
      
        ;
      
      
         未使用
      
      
         45
      
           BS_BootSig    DB 29h        
      
        ;
      
      
         擴展引導標記 (29h)
      
      
         46
      
           BS_VolID    DD 
      
        0
      
      
        ;
      
      
         卷序列號
      
      
         47
      
           BS_VolLab    DB 
      
        '
      
      
        Tinix0.01  
      
      
        '
      
      
        ;
      
      
         卷標, 必須 11 個字節
      
      
         48
      
           BS_FileSysType    DB 
      
        '
      
      
        FAT12   
      
      
        '
      
      
        ;
      
      
         文件系統類型, 必須 8個字節  
      
      
         49
      
      
         50
      
      
        LABEL_START:
      
      
         51
      
      
        mov
      
      
            ax, cs


      
      
         52
      
      
        mov
      
      
            ds, ax


      
      
         53
      
      
        mov
      
      
            es, ax


      
      
         54
      
      
        mov
      
      
            ss, ax


      
      
         55
      
      
        mov
      
      
            sp, BaseOfStack


      
      
         56
      
      
         57
      
      
        ;
      
      
         清屏
      
      
         58
      
      
        mov
      
          ax, 0600h        
      
        ;
      
      
         AH = 6,  AL = 0h
      
      
         59
      
      
        mov
      
          bx, 0700h        
      
        ;
      
      
         黑底白字(BL = 07h)
      
      
         60
      
      
        mov
      
          cx, 
      
        0
      
      
        ;
      
      
         左上角: (0, 0)
      
      
         61
      
      
        mov
      
          dx, 0184fh        
      
        ;
      
      
         右下角: (80, 50)
      
      
         62
      
      
        int
      
          10h            
      
        ;
      
      
         int 10h
      
      
         63
      
      
         64
      
      
        mov
      
          dh, 
      
        0
      
      
        ;
      
      
         "Booting  "
      
      
         65
      
      
        call
      
          DispStr            
      
        ;
      
      
         顯示字符串
      
      
         66
      
      
         67
      
      
        xor
      
          ah, ah    
      
        ;
      
      
      
         68
      
      
        xor
      
          dl, dl    
      
        ;
      
      
         ┣ 軟驅復位
      
      
         69
      
      
        int
      
          13h    
      
        ;
      
      
      
         70
      
      
         71
      
      
        ;
      
      
         下面在 A 盤的根目錄尋找 LOADER.BIN
      
      
         72
      
      
        mov
      
      
            word [wSectorNo], SectorNoOfRootDirectory


      
      
         73
      
      
        LABEL_SEARCH_IN_ROOT_DIR_BEGIN:
      
      
         74
      
      
        cmp
      
          word [wRootDirSizeForLoop], 
      
        0
      
      
        ;
      
      
      
         75
      
      
        jz
      
          LABEL_NO_LOADERBIN        
      
        ;
      
      
         ┣ 判斷根目錄區是不是已經讀完
      
      
         76
      
      
        dec
      
          word [wRootDirSizeForLoop]    
      
        ;
      
      
         ┛ 如果讀完表示沒有找到 LOADER.BIN
      
      
         77
      
      
        mov
      
      
            ax, BaseOfLoader


      
      
         78
      
      
        mov
      
          es, ax            
      
        ;
      
      
         es <- BaseOfLoader
      
      
         79
      
      
        mov
      
          bx, OffsetOfLoader    
      
        ;
      
      
         bx <- OffsetOfLoader    于是, es:bx = BaseOfLoader:OffsetOfLoader
      
      
         80
      
      
        mov
      
          ax, [wSectorNo]    
      
        ;
      
      
         ax <- Root Directory 中的某 Sector 號
      
      
         81
      
      
        mov
      
          cl, 
      
        1
      
      
         82
      
      
        call
      
      
            ReadSector


      
      
         83
      
      
         84
      
      
        mov
      
          si, LoaderFileName    
      
        ;
      
      
         ds:si -> "LOADER  BIN"
      
      
         85
      
      
        mov
      
          di, OffsetOfLoader    
      
        ;
      
      
         es:di -> BaseOfLoader:0100 = BaseOfLoader*10h+100
      
      
         86
      
      
        cld
      
      
         87
      
      
        mov
      
          dx, 10h 
      
        ;
      
      
        這里為什么是16,因為目錄項中每項為32字節,每個扇區為32字節,所以共有16項
      
      
         88
      
      
        LABEL_SEARCH_FOR_LOADERBIN:
      
      
         89
      
      
        cmp
      
          dx, 
      
        0
      
      
        ;
      
      
         ┓循環次數控制,
      
      
         90
      
      
        jz
      
          LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR    
      
        ;
      
      
         ┣如果已經讀完了一個 Sector,
      
      
         91
      
      
        dec
      
          dx                                            
      
        ;
      
      
         ┛就跳到下一個 Sector
      
      
         92
      
      
        mov
      
          cx, 
      
        11
      
      
        ;
      
      
        11個字符,有一個不一樣則不是所要找的文件
      
      
         93
      
      
        LABEL_CMP_FILENAME:
      
      
         94
      
      
        cmp
      
          cx, 
      
        0
      
      
         95
      
      
        jz
      
          LABEL_FILENAME_FOUND    
      
        ;
      
      
         如果比較了 11 個字符都相等, 表示找到
      
      
         96
      
      
        dec
      
      
            cx


      
      
         97
      
      
        lodsb
      
      
        ;
      
      
         ds:si -> al
      
      
         98
      
      
        cmp
      
          al, byte [
      
        es:
      
      
        di]


      
      
         99
      
      
        jz
      
      
            LABEL_GO_ON


      
      
        100
      
      
        jmp
      
          LABEL_DIFFERENT        
      
        ;
      
      
         只要發現不一樣的字符就表明本 DirectoryEntry 不是
      
      
        101
      
      
        ;
      
      
         我們要找的 LOADER.BIN
      
      
        102
      
      
        LABEL_GO_ON:
      
      
        103
      
      
        inc
      
      
            di


      
      
        104
      
      
        jmp
      
          LABEL_CMP_FILENAME    
      
        ;
      
      
            繼續循環
      
      
        105
      
      
        106
      
      
        LABEL_DIFFERENT:
      
      
        107
      
      
        and
      
          di, 0FFE0h                        
      
        ;
      
      
         else ┓    di &= E0 為了讓它指向本條目開頭
      
      
        108
      
      
        add
      
          di, 20h                            
      
        ;
      
      
      
        109
      
      
        mov
      
          si, LoaderFileName                    
      
        ;
      
      
             ┣ di += 20h  下一個目錄條目
      
      
        110
      
      
        jmp
      
          LABEL_SEARCH_FOR_LOADERBIN
      
        ;
      
      
      
        111
      
      
        112
      
      
        LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR:
      
      
        113
      
      
        add
      
          word [wSectorNo], 
      
        1
      
      
        114
      
      
        jmp
      
      
            LABEL_SEARCH_IN_ROOT_DIR_BEGIN


      
      
        115
      
      
        116
      
      
        LABEL_NO_LOADERBIN:
      
      
        117
      
      
        mov
      
          dh, 
      
        2
      
      
        ;
      
      
         "No LOADER."
      
      
        118
      
      
        call
      
          DispStr            
      
        ;
      
      
         顯示字符串
      
      
        119
      
      
        %ifdef    _BOOT_DEBUG_


      
      
        120
      
      
        mov
      
          ax, 4c00h        
      
        ;
      
      
      
        121
      
      
        int
      
          21h            
      
        ;
      
      
         ┛沒有找到 LOADER.BIN, 回到 DOS
      
      
        122
      
      
        %else


      
      
        123
      
      
        jmp
      
          $            
      
        ;
      
      
         沒有找到 LOADER.BIN, 死循環在這里
      
      
        124
      
      
        %endif


      
      
        125
      
      
        126
      
      
        LABEL_FILENAME_FOUND:
      
      
        ;
      
      
         找到 LOADER.BIN 后便來到這里繼續
      
      
        127
      
      
        mov
      
      
            ax, RootDirSectors


      
      
        128
      
      
        and
      
          di, 0FFE0h        
      
        ;
      
      
         di -> 當前條目的開始
      
      
        129
      
      
        add
      
          di, 01Ah        
      
        ;
      
      
         di -> 首 Sector,該條目對應的開始簇號(扇區號),看根目錄條目格式表
      
      
        130
      
      
        mov
      
          cx, word [
      
        es:
      
      
        di]


      
      
        131
      
      
        push
      
          cx            
      
        ;
      
      
         保存此 Sector 在 FAT 中的序號
      
      
        132
      
      
        add
      
      
            cx, ax


      
      
        133
      
      
        add
      
          cx, DeltaSectorNo    
      
        ;
      
      
         這句完成時 cl 里面變成 LOADER.BIN 的起始扇區號 (從 0 開始數的序號)
      
      
        134
      
      
        mov
      
      
            ax, BaseOfLoader


      
      
        135
      
      
        mov
      
          es, ax            
      
        ;
      
      
         es <- BaseOfLoader
      
      
        136
      
      
        mov
      
          bx, OffsetOfLoader    
      
        ;
      
      
         bx <- OffsetOfLoader    于是, es:bx = BaseOfLoader:OffsetOfLoader = BaseOfLoader * 10h + OffsetOfLoader
      
      
        137
      
      
        mov
      
          ax, cx            
      
        ;
      
      
         ax <- Sector 號
      
      
        138
      
      
        139
      
      
        LABEL_GOON_LOADING_FILE:
      
      
        140
      
      
        push
      
          ax            
      
        ;
      
      
      
        141
      
      
        push
      
          bx            
      
        ;
      
      
      
        142
      
      
        mov
      
          ah, 0Eh            
      
        ;
      
      
         ┃ 每讀一個扇區就在 "Booting  " 后面打一個點, 形成這樣的效果:
      
      
        143
      
      
        mov
      
          al, 
      
        '
      
      
        .
      
      
        '
      
      
        ;
      
      
      
        144
      
      
        mov
      
          bl, 0Fh            
      
        ;
      
      
         ┃ Booting ......
      
      
        145
      
      
        int
      
          10h            
      
        ;
      
      
         ┃AL=字符,BH=頁碼,BL=顏色(只適用于圖形模式)
      
      
        146
      
      
        pop
      
          bx            
      
        ;
      
      
      
        147
      
      
        pop
      
          ax            
      
        ;
      
      
      
        148
      
      
        149
      
      
        mov
      
          cl, 
      
        1
      
      
        150
      
      
        call
      
      
            ReadSector


      
      
        151
      
      
        pop
      
          ax            
      
        ;
      
      
         取出此 Sector 在 FAT 中的序號,見132行
      
      
        152
      
      
        call
      
      
            GetFATEntry


      
      
        153
      
      
        cmp
      
      
            ax, 0FFFh


      
      
        154
      
      
        jz
      
      
            LABEL_FILE_LOADED


      
      
        155
      
      
        push
      
          ax            
      
        ;
      
      
         保存 Sector 在 FAT 中的序號
      
      
        156
      
      
        mov
      
      
            dx, RootDirSectors


      
      
        157
      
      
        add
      
      
            ax, dx


      
      
        158
      
      
        add
      
      
            ax, DeltaSectorNo


      
      
        159
      
      
        add
      
      
            bx, [BPB_BytsPerSec]


      
      
        160
      
      
        jmp
      
      
            LABEL_GOON_LOADING_FILE


      
      
        161
      
      
        LABEL_FILE_LOADED:
      
      
        162
      
      
        163
      
      
        mov
      
          dh, 
      
        1
      
      
        ;
      
      
         "Ready."
      
      
        164
      
      
        call
      
          DispStr            
      
        ;
      
      
         顯示字符串
      
      
        165
      
      
        166
      
      
        ;
      
      
         *****************************************************************************************************
      
      
        167
      
      
        jmp
      
      
        BaseOfLoader:
      
      OffsetOfLoader    
      
        ;
      
      
         這一句正式跳轉到已加載到內存中的 LOADER.BIN 的開始處
      
      
        168
      
      
        ;
      
      
         開始執行 LOADER.BIN 的代碼
      
      
        169
      
      
        ;
      
      
         Boot Sector 的使命到此結束
      
      
        170
      
      
        ;
      
      
         *****************************************************************************************************
      
      
        171
      
      
        172
      
      
        173
      
      
        174
      
      
        ;
      
      
        ============================================================================
      
      
        175
      
      
        ;
      
      
        變量
      
      
        176
      
      
        ;
      
      
        ----------------------------------------------------------------------------
      
      
        177
      
       wRootDirSizeForLoop    dw    RootDirSectors    
      
        ;
      
      
         Root Directory 占用的扇區數, 在循環中會遞減至零.
      
      
        178
      
       wSectorNo        dw    
      
        0
      
      
        ;
      
      
         要讀取的扇區號
      
      
        179
      
       bOdd            db    
      
        0
      
      
        ;
      
      
         奇數還是偶數
      
      
        180
      
      
        181
      
      
        ;
      
      
        ============================================================================
      
      
        182
      
      
        ;
      
      
        字符串
      
      
        183
      
      
        ;
      
      
        ----------------------------------------------------------------------------
      
      
        184
      
       LoaderFileName        db    
      
        "
      
      
        LOADER  BIN
      
      
        "
      
      , 
      
        0
      
      
        ;
      
      
         LOADER.BIN 之文件名
      
      
        185
      
      
        ;
      
      
         為簡化代碼, 下面每個字符串的長度均為 MessageLength
      
      
        186
      
       MessageLength        equ    
      
        9
      
      
        187
      
      
        BootMessage:
      
              db    
      
        "
      
      
        Booting  
      
      
        "
      
      
        ;
      
      
         9字節, 不夠則用空格補齊. 序號 0
      
      
        188
      
       Message1        db    
      
        "
      
      
        Ready.   
      
      
        "
      
      
        ;
      
      
         9字節, 不夠則用空格補齊. 序號 1
      
      
        189
      
       Message2        db    
      
        "
      
      
        No LOADER
      
      
        "
      
      
        ;
      
      
         9字節, 不夠則用空格補齊. 序號 2
      
      
        190
      
      
        ;
      
      
        ============================================================================
      
      
        191
      
      
        192
      
      
        193
      
      
        ;
      
      
        ----------------------------------------------------------------------------
      
      
        194
      
      
        ;
      
      
         函數名: DispStr
      
      
        195
      
      
        ;
      
      
        ----------------------------------------------------------------------------
      
      
        196
      
      
        ;
      
      
         作用:
      
      
        197
      
      
        ;
      
      
            顯示一個字符串, 函數開始時 dh 中應該是字符串序號(0-based)
      
      
        198
      
      
        DispStr:
      
      
        199
      
      
        mov
      
      
            ax, MessageLength


      
      
        200
      
      
        mul
      
      
            dh


      
      
        201
      
      
        add
      
      
            ax, BootMessage


      
      
        202
      
      
        mov
      
          bp, ax            
      
        ;
      
      
      
        203
      
      
        mov
      
          ax, ds            
      
        ;
      
      
         ┣ ES:BP = 串地址
      
      
        204
      
      
        mov
      
          es, ax            
      
        ;
      
      
      
        205
      
      
        mov
      
          cx, MessageLength    
      
        ;
      
      
         CX = 串長度
      
      
        206
      
      
        mov
      
          ax, 01301h        
      
        ;
      
      
         AH = 13,  AL = 01h
      
      
        207
      
      
        mov
      
          bx, 0007h        
      
        ;
      
      
         頁號為0(BH = 0) 黑底白字(BL = 07h)
      
      
        208
      
      
        mov
      
          dl, 
      
        0
      
      
        209
      
      
        int
      
          10h            
      
        ;
      
      
         int 10h
      
      
        210
      
      
        ret
      
      
        211
      
      
        212
      
      
        213
      
      
        ;
      
      
        ----------------------------------------------------------------------------
      
      
        214
      
      
        ;
      
      
         函數名: ReadSector
      
      
        215
      
      
        ;
      
      
        ----------------------------------------------------------------------------
      
      
        216
      
      
        ;
      
      
         作用:
      
      
        217
      
      
        ;
      
      
            從第 ax 個 Sector 開始, 將 cl 個 Sector 讀入 es:bx 中
      
      
        218
      
      
        ReadSector:
      
      
        219
      
      
        ;
      
      
         -----------------------------------------------------------------------
      
      
        220
      
      
        ;
      
      
         怎樣由扇區號求扇區在磁盤中的位置 (扇區號 -> 柱面號, 起始扇區, 磁頭號)
      
      
        221
      
      
        ;
      
      
         -----------------------------------------------------------------------
      
      
        222
      
      
        ;
      
      
         設扇區號為 x
      
      
        223
      
      
        ;
      
      
                                   ┌ 柱面號 = y >> 1
      
      
        224
      
      
        ;
      
      
               x           ┌ 商 y ┤
      
      
        225
      
      
        ;
      
      
         -------------- => ┤      └ 磁頭號 = y & 1
      
      
        226
      
      
        ;
      
      
          每磁道扇區數     │
      
      
        227
      
      
        ;
      
      
                           └ 余 z => 起始扇區號 = z + 1
      
      
        228
      
      
        push
      
      
            bp


      
      
        229
      
      
        mov
      
      
            bp, sp


      
      
        230
      
      
        sub
      
          esp, 
      
        2
      
      
        ;
      
      
         辟出兩個字節的堆棧區域保存要讀的扇區數: byte [bp-2]
      
      
        231
      
      
        232
      
      
        mov
      
          byte [bp-
      
        2
      
      
        ], cl


      
      
        233
      
      
        push
      
          bx            
      
        ;
      
      
         保存 bx
      
      
        234
      
      
        mov
      
          bl, [BPB_SecPerTrk]    
      
        ;
      
      
         bl: 除數
      
      
        235
      
      
        div
      
          bl            
      
        ;
      
      
         y 在 al 中, z 在 ah 中
      
      
        236
      
      
        inc
      
          ah            
      
        ;
      
      
         z ++
      
      
        237
      
      
        mov
      
          cl, ah            
      
        ;
      
      
         cl <- 起始扇區號
      
      
        238
      
      
        mov
      
          dh, al            
      
        ;
      
      
         dh <- y
      
      
        239
      
      
        shr
      
          al, 
      
        1
      
      
        ;
      
      
         y >> 1 (其實是 y/BPB_NumHeads, 這里BPB_NumHeads=2)
      
      
        240
      
      
        mov
      
          ch, al            
      
        ;
      
      
         ch <- 柱面號
      
      
        241
      
      
        and
      
          dh, 
      
        1
      
      
        ;
      
      
         dh & 1 = 磁頭號
      
      
        242
      
      
        pop
      
          bx            
      
        ;
      
      
         恢復 bx
      
      
        243
      
      
        ;
      
      
         至此, "柱面號, 起始扇區, 磁頭號" 全部得到 ^^^^^^^^^^^^^^^^^^^^^^^^
      
      
        244
      
      
        mov
      
          dl, [BS_DrvNum]        
      
        ;
      
      
         驅動器號 (0 表示 A 盤)
      
      
        245
      
       .
      
        GoOnReading:
      
      
        246
      
      
        mov
      
          ah, 
      
        2
      
      
        ;
      
      
      
        247
      
      
        mov
      
          al, byte [bp-
      
        2
      
      ]        
      
        ;
      
      
         讀 al 個扇區
      
      
        248
      
      
        int
      
      
            13h


      
      
        249
      
      
        jc
      
          .GoOnReading        
      
        ;
      
      
         如果讀取錯誤 CF 會被置為 1, 這時就不停地讀, 直到正確為止
      
      
        250
      
      
        251
      
      
        add
      
          esp, 
      
        2
      
      
        252
      
      
        pop
      
      
            bp


      
      
        253
      
      
        254
      
      
        ret
      
      
        255
      
      
        256
      
      
        ;
      
      
        ----------------------------------------------------------------------------
      
      
        257
      
      
        ;
      
      
         函數名: GetFATEntry
      
      
        258
      
      
        ;
      
      
        ----------------------------------------------------------------------------
      
      
        259
      
      
        ;
      
      
         作用:
      
      
        260
      
      
        ;
      
      
            找到序號為 ax 的 Sector 在 FAT 中的條目, 結果放在 ax 中
      
      
        261
      
      
        ;
      
      
            需要注意的是, 中間需要讀 FAT 的扇區到 es:bx 處, 所以函數一開始保存了 es 和 bx
      
      
        262
      
      
        GetFATEntry:
      
      
        263
      
      
        push
      
      
            es


      
      
        264
      
      
        push
      
      
            bx


      
      
        265
      
      
        push
      
      
            ax


      
      
        266
      
      
        mov
      
          ax, BaseOfLoader    
      
        ;
      
      
      
        267
      
      
        sub
      
          ax, 0100h        
      
        ;
      
      
         ┣ 在 BaseOfLoader 后面留出 4K 空間用于存放 FAT,注意這里是0100,而不是01000
      
      
        268
      
      
        mov
      
          es, ax            
      
        ;
      
      
      
        269
      
      
        pop
      
      
            ax


      
      
        270
      
      
        mov
      
          byte [bOdd], 
      
        0
      
      
        271
      
      
        mov
      
          bx, 
      
        3
      
      
        272
      
      
        mul
      
          bx            
      
        ;
      
      
         dx:ax = ax * 3
      
      
        273
      
      
        mov
      
          bx, 
      
        2
      
      
        274
      
      
        div
      
          bx            
      
        ;
      
      
         dx:ax / 2  ==>  ax <- 商, dx <- 余數
      
      
        275
      
      
        cmp
      
          dx, 
      
        0
      
      
        276
      
      
        jz
      
      
            LABEL_EVEN


      
      
        277
      
      
        mov
      
          byte [bOdd], 
      
        1
      
      
        278
      
      
        LABEL_EVEN:
      
      
        ;
      
      
        偶數
      
      
        279
      
      
        xor
      
          dx, dx            
      
        ;
      
      
         現在 ax 中是 FATEntry 在 FAT 中的偏移量. 下面來計算 FATEntry 在哪個扇區中(FAT占用不止一個扇區)
      
      
        280
      
      
        mov
      
      
            bx, [BPB_BytsPerSec]


      
      
        281
      
      
        div
      
          bx            
      
        ;
      
      
         dx:ax / BPB_BytsPerSec  ==>    ax <- 商   (FATEntry 所在的扇區相對于 FAT 來說的扇區號)
      
      
        282
      
      
        ;
      
      
                        dx <- 余數 (FATEntry 在扇區內的偏移)。
      
      
        283
      
      
        push
      
      
            dx


      
      
        284
      
      
        mov
      
          bx, 
      
        0
      
      
        ;
      
      
         bx <- 0    于是, es:bx = (BaseOfLoader - 100):00 = (BaseOfLoader - 100) * 10h
      
      
        285
      
      
        add
      
          ax, SectorNoOfFAT1    
      
        ;
      
      
         此句執行之后的 ax 就是 FATEntry 所在的扇區號
      
      
        286
      
      
        mov
      
          cl, 
      
        2
      
      
        287
      
      
        call
      
          ReadSector        
      
        ;
      
      
         讀取 FATEntry 所在的扇區, 一次讀兩個, 避免在邊界發生錯誤, 因為一個 FATEntry 可能跨越兩個扇區
      
      
        288
      
      
        pop
      
      
            dx


      
      
        289
      
      
        add
      
      
            bx, dx


      
      
        290
      
      
        mov
      
          ax, [
      
        es:
      
      
        bx]


      
      
        291
      
      
        cmp
      
          byte [bOdd], 
      
        1
      
      
        292
      
      
        jnz
      
      
            LABEL_EVEN_2


      
      
        293
      
      
        shr
      
          ax, 
      
        4
      
      
        294
      
      
        LABEL_EVEN_2:
      
      
        295
      
      
        and
      
      
            ax, 0FFFh


      
      
        296
      
      
        297
      
      
        LABEL_GET_FAT_ENRY_OK:
      
      
        298
      
      
        299
      
      
        pop
      
      
            bx


      
      
        300
      
      
        pop
      
      
            es


      
      
        301
      
      
        ret
      
      
        302
      
      
        ;
      
      
        ----------------------------------------------------------------------------
      
      
        303
      
      
        304
      
       times     
      
        510
      
      -($-$$)    db    
      
        0
      
      
        ;
      
      
         填充剩下的空間,使生成的二進制代碼恰好為512字節
      
      
        305
      
       dw     0xaa55                
      
        ;
      
      
         結束標志
      
    

參考:

http://blog.chinaunix.net/uid-27024249-id-3449728.html

http://blog.csdn.net/robbie1314/article/details/5765117

http://blog.csdn.net/asd8182651/article/details/7388541

第四章boot.asm


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美特黄a级高清免费大片 欧美特黄a级猛片a级 | 精品特级一级毛片免费观看 | 狠狠色丁香久久婷婷综合五月 | 亚洲欧美日韩国产精品26u | 亚洲综合色丁香麻豆 | 亚洲欧美一 | 黑人和黑人激情一级毛片 | 午夜狠狠操| 国产不卡在线观看视频 | 久操精品视频 | 成人精品一区二区激情 | 黑人一级毛片 | 日本国产一区二区三区 | 一级毛片视频 | 成人精品视频 成人影院 | 欧美一级毛片免费大全 | 日韩午夜在线观看 | 国产男女爽爽爽免费视频 | 青草青青在线观看免费视频 | 特级特黄一级乱仑 | 国产伦码精品一区二区三区 | 一区二区三区精品国产欧美 | 国产一区二区三区免费看 | 日本精品中文字幕在线不卡 | 久久精品免视看国产陈冠希 | 日韩欧免费一区二区三区 | 成人在色线视频在线观看免费大全 | 久久国产精品-久久精品 | 一区二区三区四区日韩 | 欧美一级毛片特黄黄 | 快射视频欧美 | 337p欧洲亚洲大胆艺术 | 久久香蕉国产线看观看网站 | 久久香蕉精品 | 97av麻豆蜜桃一区二区 | 国产精品国产三级国产普通话 | 亚洲另类图片专区 | 美女伊人| 亚洲成人看片 | 天天色狠狠干 | 国产精品免费一区二区区 |