小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

NT,2000,XP 的 CDROM 引導(dǎo)扇區(qū)代碼分析

 johnlane 2007-06-17

NT,2000,XP 的 CDROM 引導(dǎo)扇區(qū)代碼分析

分類 : 其他    發(fā)布時間 : 2007-05-20    來源 : Auto5.info

NT,2000,XP 的 CDROM 引導(dǎo)扇區(qū)代碼分析
07C0:0000 FA      cli             ;禁止中斷
07C0:0001 33C0     xor ax, ax
07C0:0003 8ED0     mov ss, ax         ;初始化運行堆棧,將 SS:SP 指向運行代碼前
07C0:0005 BC007C    mov sp, 7C00
07C0:0008 FB      sti             ;允許中斷
07C0:0009 8CC8     mov ax, cs
07C0:000B 8ED8     mov ds, ax         ;將 DS 指向 CS 相同地址,此處操作比較浪費,只用了一次
07C0:000D 52      push dx           ;引導(dǎo)扇區(qū)運行時 DX 保存當(dāng)前引導(dǎo)磁盤號

;下面幾條指令用于取得裝入偏移地址,由于不能直接對 IP 進行 mov 指令
;所以使用一條 CALL 指令利用堆棧將 IP 取出

07C0:000E E80000    call 0011          ;執(zhí)行一條函數(shù)調(diào)用指令,從而將下一條指令的地址壓入堆棧
07C0:0011 5E      pop si           ;取出剛剛壓入的地址
07C0:0012 81EE1100   sub si, 0011        ;減掉偏轉(zhuǎn)地址得到實際的開始偏移
07C0:0016 7412     je 002A           ;如果偏移為零跳轉(zhuǎn)

;判斷裝入地址是否為 0000:7C00 如果是則使用遠(yuǎn)跳轉(zhuǎn)進行地址轉(zhuǎn)換到 0037

07C0:0018 81FE007C   cmp si, 7C00        ;裝入偏移是否為 7C00
07C0:001C 7575     jne 0093
07C0:001E 8CC8     mov ax, cs         ;取得裝入段地址,此句多余,見 0009
07C0:0020 3D0000    cmp ax, 0000        ;裝入段地址是否為 0000
07C0:0023 757F     jne 00A4
07C0:0025 EA3700C007  jmp 0037          ;使用遠(yuǎn)跳轉(zhuǎn)指令進行地址轉(zhuǎn)換

;判斷裝入地址是否為 0000 如果是則直接進行運行到 0037

07C0:002A C606AE0133  mov byte ptr [01AE], 33   ;修改錯誤代碼為 "3",意義為裝載地址錯誤
07C0:002F 90      nop
07C0:0030 8CC8     mov ax, cs         ;多余,同 001E
07C0:0032 3DC007    cmp ax, 07C0        ;裝入段地址是否為 07C0
07C0:0035 757E     jne 00B5

;前面這段代碼用于解決不同系統(tǒng)裝入地址的問題,合法地址為 0000:7C00 或 07C0:0000
;如果地址不正確,則進行錯誤處理,運行到此處地址應(yīng)全部轉(zhuǎn)換為 07C0:0037

07C0:0037 8CC8     mov ax, cs         ;取什么取,一定是 07C0 了
07C0:0039 8ED8     mov ds, ax         ;這次才真的有用,見 000B
07C0:003B C606AE0134  mov byte ptr [01AE], 34   ;修改錯誤代碼為 "4",意義為非法引導(dǎo)盤
07C0:0040 90      nop
07C0:0041 80FA80    cmp dl, 80         ;查看當(dāng)前引導(dǎo)磁盤號是否小于 80 ,即不是硬盤或 CDROM
07C0:0044 726F     jb 00B5           ;如果是則轉(zhuǎn)移錯誤處理

07C0:0046 C606AE0135  mov byte ptr [01AE], 35   ;修改錯誤代碼為 "5",意義為引導(dǎo)扇區(qū)非法或不完整
07C0:004B 90      nop
07C0:004C BBFE07    mov bx, 07FE        ;BX 指向引導(dǎo)扇區(qū)結(jié)尾標(biāo)志
07C0:004F 8B07     mov ax, [bx]        ;取出標(biāo)志
07C0:0051 3D55AA    cmp ax, AA55        ;是否為 AA55
07C0:0054 755F     jne 00B5          ;如果不是,則轉(zhuǎn)移錯誤處理

;裝載 BOOTFIX.BIN 并運行,顯示 "Press any key to boot from CD"
;如果沒有此文件則直接跳過

07C0:0056 5A      pop dx           ;恢復(fù)引導(dǎo)磁盤號
07C0:0057 88169904   mov [0499], dl       ;保存磁盤號至數(shù)據(jù)區(qū)
07C0:005B 688A04    push 048A          ;"BOOTFIX.BIN" 文件名的地址
07C0:005E 6A0B     push 000B          ;文件名長度為 11
07C0:0060 680020    push 2000          ;裝載起始段地址 2000
07C0:0063 E87603    call 03DC          ;調(diào)用裝載函數(shù)
07C0:0066 0F820F00   jb 0079           ;如果不成功則直接跳過

07C0:006A 60      pusha
07C0:006B 1E      push ds
07C0:006C 06      push es           ;保存當(dāng)前運行現(xiàn)場
07C0:006D 8A169904   mov dl, [0499]       ;取出當(dāng)前引導(dǎo)磁盤號
07C0:0071 9A00000020  call 2000:0000       ;運行剛剛裝載的 BOOTFIX.BIN
07C0:0076 07      pop es
07C0:0077 1F      pop ds
07C0:0078 61      popa            ;恢復(fù)運行現(xiàn)場

;裝載 SETUPLDR.BIN 并運行

07C0:0079 687E04    push 047E          ;"SETUPLDR.BIN" 文件名的地址
07C0:007C 6A0C     push 000C          ;文件名長度為 12
07C0:007E 680020    push 2000          ;裝載起始段地址 2000
07C0:0081 E85803    call 03DC          ;調(diào)用裝載函數(shù)
07C0:0084 0F823500   jb 00BD           ;如果不成功則轉(zhuǎn)錯誤處理

07C0:0088 8A169904   mov dl, [0499]       ;取出當(dāng)前引導(dǎo)磁盤號
07C0:008C 33C0     xor ax, ax
07C0:008E 680020    push 2000
07C0:0091 50      push ax           ;在堆棧中制造 2000:0000 的返回地址
07C0:0092 CB      retf            ;轉(zhuǎn)移到 2000:0000 運行剛裝載的 SETUPLDR.BIN

;由 07C0:001C 轉(zhuǎn)此

07C0:0093 56      push si
07C0:0094 8BDE     mov bx, si
07C0:0096 81C3AE01   add bx, 01AE        ;計算偏移
07C0:009A C60731    mov byte ptr [bx], 31    ;修改錯誤代碼為 "1",意義為引導(dǎo)段地址錯誤
07C0:009D 81C68A01   add si, 018A        ;"CDBOOT: Cannot boot from CD - Code: "
07C0:00A1 EB2A     jmp 00CD          ;顯示并重新引導(dǎo)

07C0:00A3 90      nop

;由 07C0:0023 轉(zhuǎn)此

07C0:00A4 56      push si
07C0:00A5 8BDE     mov bx, si
07C0:00A7 81C3AE01   add bx, 01AE
07C0:00AB C60732    mov byte ptr [bx], 32    ;修改錯誤代碼為 "2",意義為引導(dǎo)偏移地址錯誤
07C0:00AE 81C68A01   add si, 018A        ;"CDBOOT: Cannot boot from CD - Code: "
07C0:00B2 EB19     jmp 00CD          ;顯示并重新引導(dǎo)

07C0:00B4 90      nop

;由 07C0:0035, 07C0:0044, 07C0:0054 轉(zhuǎn)此

07C0:00B5 6A00     push 0000
07C0:00B7 BE8A01    mov si, 018A        ;"CDBOOT: Cannot boot from CD - Code: "
07C0:00BA EB11     jmp 00CD          ;顯示并重新引導(dǎo)

07C0:00BC 90      nop

;由 07C0:0084 轉(zhuǎn)此

07C0:00BD 6A00     push 0000
07C0:00BF BEB201    mov si, 01B2        ;"CDBOOT: Couldn‘t find NTLDR"
07C0:00C2 EB09     jmp 00CD          ;顯示并重新引導(dǎo)

07C0:00C4 90      nop

;由 07C0:0367 轉(zhuǎn)此

07C0:00C5 6A00     push 0000
07C0:00C7 BED001    mov si, 01D0        ;"CDBOOT: Memory overflow error"
07C0:00CA EB01     jmp 00CD          ;顯示并重新引導(dǎo)

07C0:00CC 90      nop

;顯示并重新引導(dǎo),si 中為要顯示的信息

07C0:00CD E80400    call 00D4          ;顯示 si 中的信息
07C0:00D0 5E      pop si           ;恢復(fù)引導(dǎo)扇區(qū)被裝載的偏移地址
07C0:00D1 EB12     jmp 00E5          ;開始錯誤處理

07C0:00D3 90      nop

;顯示信息函數(shù),入口:
;si: 信息起始地址, 0 結(jié)尾

07C0:00D4 AC      lodsb            ;取一個字符
07C0:00D5 0AC0     or al , al         ;是否結(jié)尾
07C0:00D7 0F840900   je 00E4
07C0:00DB B40E     mov ah, 0E
07C0:00DD BB0700    mov bx, 0007
07C0:00E0 CD10     int 10           ;顯示
07C0:00E2 EBF0     jmp 00D4
07C0:00E4 C3      ret

;錯誤處理,此間地址可能因裝載地址不同有所不同,所以使用 si 作為基礎(chǔ)地址進行地址運算

;首先延時 0024 次時鐘中斷,即 36 * 55 = 1980 ms,大約兩秒

07C0:00E5 C7846B042400 mov word ptr [si+046B], 0024 ;設(shè)定延時計數(shù)器為 0024
07C0:00EB FA      cli
07C0:00EC 06      push es
07C0:00ED 33C0     xor ax, ax
07C0:00EF 8EC0     mov es, ax         ;es 指向中斷地址表
07C0:00F1 BB2000    mov bx, 0020        ;bx 指向中斷 08 的偏移
07C0:00F4 268B07    mov ax, es:[bx]
07C0:00F7 89846704   mov [si+0467], ax
07C0:00FB 268B4702   mov ax, es:[bx+02]
07C0:00FF 89846904   mov [si+0469], ax      ;保存原中斷 08 的地址到 0467
07C0:0103 268937    mov es:[bx], si
07C0:0106 2681076D01  add word ptr es:[bx], 016D
07C0:010B 268C4F02   mov es:[bx+02], cs     ;將中斷 08 指向 07C0:016B
07C0:010F 07      pop es
07C0:0110 FB      sti
07C0:0111 83BC6B0400  cmp word ptr [si+046B], 0000 ;查看計數(shù)器是否結(jié)束
07C0:0116 75F9     jne 0111
07C0:0118 FA      cli
07C0:0119 06      push es
07C0:011A 33C0     xor ax, ax
07C0:011C 8EC0     mov es, ax
07C0:011E BB2000    mov bx, 0020
07C0:0121 8B846704   mov ax, [si+0467]
07C0:0125 268907    mov es:[bx], ax
07C0:0128 8B846904   mov ax, [si+0469]
07C0:012C 26894702   mov es:[bx+02], ax     ;恢復(fù)剛才保存的中斷 08 的地址
07C0:0130 07      pop es
07C0:0131 FB      sti

;將引導(dǎo)扇區(qū)代碼移動到 2000:0000,以便在 07C0:0000 裝載新的引導(dǎo)扇區(qū)

07C0:0132 1E      push ds
07C0:0133 06      push es
07C0:0134 B80020    mov ax, 2000
07C0:0137 8EC0     mov es, ax
07C0:0139 8CC8     mov ax, cs
07C0:013B 8ED8     mov ds, ax
07C0:013D 33FF     xor di, di
07C0:013F B90008    mov cx, 0800
07C0:0142 F3      repz
07C0:0143 A4      movsb
07C0:0144 07      pop es
07C0:0145 1F      pop ds
07C0:0146 EA4B010020  jmp 2000:014B        ;轉(zhuǎn)移到

;在 07C0:0000 裝載硬盤的引導(dǎo)扇區(qū)此段代碼執(zhí)行時已經(jīng)被移動到 2000:014B

07C0:014B 06      push es
07C0:014C B8C007    mov ax, 07C0
07C0:014F 8EC0     mov es, ax
07C0:0151 BB0000    mov bx, 0000
07C0:0154 B80102    mov ax, 0201
07C0:0157 B90100    mov cx, 0001
07C0:015A BA8000    mov dx, 0080
07C0:015D CD13     int 13
07C0:015F 0F830200   jnb 0165
07C0:0163 EBFE     jmp 0163          ;如果裝載失敗,則死循環(huán)

07C0:0165 07      pop es
07C0:0166 B280     mov dl, 80
07C0:0168 EA007C0000  jmp 0000:7C00        ;轉(zhuǎn)移到硬盤引導(dǎo)扇區(qū)處理

;新的中斷 08 處理程序,每次中斷產(chǎn)生都將計數(shù)器減一,減至零為止

07C0:016D 9C      pushf
07C0:016E FA      cli
07C0:016F 2E83BC6B0400 cmp word ptr cs:[si+046B], 0000 ;計數(shù)器是否為零
07C0:0175 0F840500   je 017E
07C0:0179 2EFF8C6B04  dec word ptr cs:[si+046B]  ;不為零則減一
07C0:017E 9D      popf
07C0:017F 2EFFB46904  push word ptr cs:[si+0469]
07C0:0184 2EFFB46704  push word ptr cs:[si+0467] ;將原中斷地址壓入堆棧
07C0:0189 CB      retf            ;轉(zhuǎn)入系統(tǒng)中斷處理程序繼續(xù)處理

;錯誤提示信息

07C0:018A        DB "CDBOOT: Cannot boot from CD - Code: "
07C0:01AE        DB "0", 0D, 0A, 00         ;錯誤代碼
07C0:01B2        DB "CDBOOT: Couldn‘t find NTLDR", 0D, 0A, 00
07C0:01D0        DB "CDBOOT: Memory overflow error", 0D, 0A, 00

;以下為前面的代碼中使用的函數(shù)

;從剛剛讀取的目錄中搜索指定的字符串
;這段的作用就是在整個目錄中查找指定的文件
;查找的時候考慮了遠(yuǎn)指針的最小化偏移
;并且考慮了跨段的查找問題
;純粹算法,沒什么邏輯,所以比較煩瑣,也比較無聊
;如果想了解的話可以自己查 iso9660 里面有關(guān)目錄項的內(nèi)容去一行行詳細(xì)分析

07C0:01F0 C606B10400  mov byte ptr [04B1], 00 ;
07C0:01F5 90      nop
07C0:01F6 8B0E9E04   mov cx, [049E]       ;取出讀取的字符數(shù)低位
07C0:01FA FC      cld
07C0:01FB 33DB     xor bx, bx         ;es:bx 指向目錄開始
07C0:01FD 33D2     xor dx, dx

07C0:01FF 8B36AD04   mov si, [04AD]       ;要搜索的字符串的地址
07C0:0203 268A17    mov dl, es:[bx]       ;取該目錄項長度
07C0:0206 80FA00    cmp dl, 00         ;如果長度為零,則跳過該項
07C0:0209 0F843B00   je 0248

07C0:020D 8BC3     mov ax, bx
07C0:020F 052100    add ax, 0021        ;加 21H 指向目錄項中文件名
07C0:0212 8BF8     mov di, ax
07C0:0214 51      push cx
07C0:0215 33C9     xor cx, cx
07C0:0217 8A0EAF04   mov cl , [04AF]       ;cx 為字符串長度
07C0:021B F3      repz
07C0:021C A6      cmpsb            ;比較字符串
07C0:021D 59      pop cx
07C0:021E 0F846F00   je 0291           ;如果相同

07C0:0222 3BD1     cmp dx, cx         ;比較目錄項長度與總長度的低位
07C0:0224 0F833700   jnb 025F ;如果不足則處理總長度高位

07C0:0228 2BCA     sub cx, dx         ;從總長度低位中減掉當(dāng)前目錄項長度
07C0:022A 803EB10401  cmp byte ptr [04B1], 01
07C0:022F 0F841A00   je 024D

07C0:0233 03D3     add dx, bx ;偏移地址加本目錄項指向下一目錄項
07C0:0235 8BDA     mov bx, dx
07C0:0237 83E30F    and bx, 000F
07C0:023A 51      push cx
07C0:023B B104     mov cl, 04
07C0:023D D3EA     shr dx, cl
07C0:023F 59      pop cx
07C0:0240 8CC0     mov ax, es
07C0:0242 03C2     add ax, dx
07C0:0244 8EC0     mov es, ax         ;最小化遠(yuǎn)指針偏移
07C0:0246 EBB7     jmp 01FF

07C0:0248 BA0100    mov dx, 0001 ;設(shè)定長度為一,直接進入下次比較
07C0:024B EBD5     jmp 0222

07C0:024D 41      inc cx
07C0:024E C606B10400  mov byte ptr [04B1], 00
07C0:0253 90      nop
07C0:0254 EBDD     jmp 0233

07C0:0256 C606B10401  mov byte ptr [04B1], 01
07C0:025B 90      nop
07C0:025C EB29     jmp 0287

07C0:025E 90      nop
07C0:025F 833EA00400  cmp word ptr [04A0], 0000 ;總長度高位是否為零
07C0:0264 0F850200   jne 026A ;如果不為零則繼續(xù)處理
07C0:0268 F9      stc ;沒有找到
07C0:0269 C3      ret

07C0:026A 832EA00401  sub word ptr [04A0], 0001 ;高位減一
07C0:026F 03DA     add bx, dx ;偏移地址加本目錄項指向下一目錄項

07C0:0271 53      push bx

07C0:0272 51      push cx
07C0:0273 B104     mov cl, 04
07C0:0275 D3EB     shr bx, cl
07C0:0277 59      pop cx
07C0:0278 8CC0     mov ax, es
07C0:027A 03C3     add ax, bx
07C0:027C 8EC0     mov es, ax         ;最小化遠(yuǎn)指針偏移
07C0:027E 5B      pop bx
07C0:027F 83E30F    and bx, 000F

07C0:0282 2BD1     sub dx, cx
07C0:0284 74D0     je 0256

07C0:0286 4A      dec dx
07C0:0287 B8FFFF    mov ax, FFFF
07C0:028A 2BC2     sub ax, dx
07C0:028C 8BC8     mov cx, ax ;得到新的總長度的地位剩余值
07C0:028E E96EFF    jmp 01FF ;繼續(xù)查找

07C0:0291 803EB00401  cmp byte ptr [04B0], 01 ;此次查找是否是子目錄
07C0:0296 0F840A00   je 02A4 ;如果是子目錄則轉(zhuǎn)子目錄屬性檢查
07C0:029A 26F6471902  test byte ptr es:[bx+19], 02 ;查看目錄屬性是否為文件
07C0:029F 7581     jne 0222 ;如果不是繼續(xù)查找
07C0:02A1 EB0A     jmp 02AD

07C0:02A3 90      nop
07C0:02A4 26F6471902  test byte ptr es:[bx+19], 02 ;查看目錄屬性是否為子目錄
07C0:02A9 0F8475FF   je 0222 ;如果不是則繼續(xù)查找

07C0:02AD A0AF04    mov al, [04AF]
07C0:02B0 26384720   cmp es:[bx+20], al ;比較文件名長度
07C0:02B4 0F856AFF   jne 0222 ;不相同則繼續(xù)比較
07C0:02B8 F8      clc ;清除標(biāo)記,查找成功
07C0:02B9 C3      ret

;下面的幾個函數(shù)使用了類 C 的參數(shù)傳遞方法
;所以大家看到了熟悉的 push bp / mov bp, sp 指令對
;但是顯然作者對高級語言函數(shù)堆棧組織不很熟悉,
;連函數(shù)結(jié)尾的 mov sp, bp 也生搬了過來
;這條指令是高級語言用來釋放自動局部變量的
;而這里的幾個函數(shù)則根本沒有使用局部變量
;其實如果使用局部變量的話這里的幾個函數(shù)會比較好看一些,
;我指的是看起來比較象 C 的反匯編代碼
;呵呵

;讀指定扇區(qū)到內(nèi)存,使用擴展磁盤讀寫
;考慮到 DOS 下的 64K 數(shù)據(jù)段的限制, 讀操作是循環(huán)執(zhí)行的.

07C0:02BA 55      push bp
07C0:02BB 8BEC     mov bp, sp
07C0:02BD 53      push bx
07C0:02BE 56      push si
07C0:02BF 52      push dx
07C0:02C0 50      push ax           ;保存寄存器

07C0:02C1 BB6D04    mov bx, 046D        ;bx 指向擴展磁盤讀結(jié)構(gòu)
07C0:02C4 C60710    mov byte ptr [bx], 10
07C0:02C7 C6470100   mov byte ptr [bx+01], 00
07C0:02CB C6470300   mov byte ptr [bx+03], 00
07C0:02CF C747040000  mov word ptr [bx+04], 0000
07C0:02D4 C7470C0000  mov word ptr [bx+0C], 0000
07C0:02D9 C7470E0000  mov word ptr [bx+0E], 0000 ;全部清除

;將調(diào)用參數(shù)復(fù)制到臨時數(shù)據(jù)區(qū)

07C0:02DE 8B460C    mov ax, [bp+0C]
07C0:02E1 A3A204    mov [04A2], ax
07C0:02E4 8B460A    mov ax, [bp+0A]
07C0:02E7 A3A404    mov [04A4], ax       ;讀盤總扇區(qū)數(shù),32 位,分兩次處理

07C0:02EA 8B4608    mov ax, [bp+08]
07C0:02ED A3A604    mov [04A6], ax       ;數(shù)據(jù)區(qū)的段地址

07C0:02F0 8B4606    mov ax, [bp+06]
07C0:02F3 A3A804    mov [04A8], ax
07C0:02F6 8B4604    mov ax, [bp+04]
07C0:02F9 A3AA04    mov [04AA], ax       ;開始邏輯扇區(qū)號,32位

;以上將調(diào)用時傳遞的參數(shù)保存在數(shù)據(jù)區(qū)以便使用,
;其實大可不必,既然用了類 C 的參數(shù)傳遞,
;那么完全可以直接使用這些實參當(dāng)變量用

07C0:02FC 813EA4040000 cmp word ptr [04A4], 0000
07C0:0302 0F851900   jne 031F
07C0:0306 813EA2042000 cmp word ptr [04A2], 0020
07C0:030C 0F8F0F00   jg 031F           ;總扇區(qū)數(shù)是否小于 20

;保證每次讀取的數(shù)據(jù)量不超過 64K.
;如果總扇區(qū)數(shù)小于 20H ,即 20H * 800H = 10000H, 正好是 64K 一個數(shù)據(jù)段的尺寸
;注意,這里處理的是 CDROM 的扇區(qū), 所以扇區(qū)大小是 800H, 2048 字節(jié)

07C0:0310 C6067D0400  mov byte ptr [047D], 00   ;清除標(biāo)記標(biāo)示不需段處理
07C0:0315 90      nop
07C0:0316 A1A204    mov ax, word ptr [04A2]
07C0:0319 A2AC04    mov byte ptr [04AC], al   ;直接讀取總扇區(qū)數(shù)
07C0:031C EB0D     jmp 032B

07C0:031E 90      nop
07C0:031F C6067D0401  mov byte ptr [047D], 01   ;置標(biāo)記標(biāo)示需要段處理
07C0:0324 90      nop
07C0:0325 C606AC0420  mov byte ptr [04AC], 20   ;每次固定讀取 20 個扇區(qū),即 64K 數(shù)據(jù)
07C0:032A 90      nop

07C0:032B A0AC04    mov al, [04AC]         
07C0:032E 884702    mov [bx+02], al       ;扇區(qū)數(shù)

07C0:0331 A1A604    mov ax, [04A6]
07C0:0334 894706    mov [bx+06], ax       ;數(shù)據(jù)區(qū)的段地址

07C0:0337 A1A804    mov ax, [04A8]
07C0:033A 894708    mov [bx+08], ax
07C0:033D A1AA04    mov ax, [04AA]
07C0:0340 89470A    mov [bx+0A], ax       ;開始邏輯扇區(qū)號

07C0:0343 BE6D04    mov si, 046D
07C0:0346 B442     mov ah, 42
07C0:0348 8A169904   mov dl, [0499]       ;取出引導(dǎo)磁盤號
07C0:034C CD13     int 13           ;操作

07C0:034E 803E7D0401  cmp byte ptr [047D], 01   ;是否還需要讀取?
07C0:0353 0F852200   jne 0379

07C0:0357 832EA20420  sub word ptr [04A2], 0020
07C0:035C 831EA40400  sbb word ptr [04A4], 0000  ;總扇區(qū)數(shù)減掉 20

07C0:0361 8106A6040010 add word ptr [04A6], 1000  ;數(shù)據(jù)段地址減掉 1000, 指向下一個 64K.
07C0:0367 0F825AFD   jb 00C5           ;如果溢出則轉(zhuǎn)錯誤

07C0:036B 8106A8042000 add word ptr [04A8], 0020
07C0:0371 8116AA040000 adc word ptr [04AA], 0000  ;開始邏輯扇區(qū)號加 20

07C0:0377 EB83     jmp 02FC          ;開始下一次循環(huán)讀取

07C0:0379 58      pop ax           ;恢復(fù)寄存器
07C0:037A 5A      pop dx
07C0:037B 5E      pop si
07C0:037C 5B      pop bx
07C0:037D 8BE5     mov sp, bp
07C0:037F 5D      pop bp
07C0:0380 C3      ret


;從指定扇區(qū)開始讀取指定的字節(jié)數(shù)到內(nèi)存
;調(diào)用 02BA 完成讀取
07C0:0381 55      push bp
07C0:0382 8BEC     mov bp, sp
07C0:0384 51      push cx
07C0:0385 53      push bx
07C0:0386 50      push ax

;將字節(jié)數(shù)轉(zhuǎn)換為邏輯扇區(qū)數(shù),不足一個扇區(qū)按照一個扇區(qū)計算
07C0:0387 B10B     mov cl, 0B
07C0:0389 8B1EA004   mov bx, [04A0]
07C0:038D A19E04    mov ax, [049E]
07C0:0390 0FADD8    shrd ax, bx, cl
07C0:0393 D3EB     shr bx, cl         ;將 bx:ax 右移 11 位,即除 2048
07C0:0395 F7069E04FF07 test word ptr [049E], 07FF ;低位是否為零
07C0:039B 7406     je 03A3
07C0:039D 050100    add ax, 0001
07C0:03A0 83D300    adc bx, 0000        ;不是則加一

07C0:03A3 50      push ax
07C0:03A4 53      push bx           ;總扇區(qū)數(shù)
07C0:03A5 FF7604    push word ptr [bp+04]    ;段地址
07C0:03A8 FF369A04   push word ptr [049A]
07C0:03AC FF369C04   push word ptr [049C]    ;開始邏輯扇區(qū)號
07C0:03B0 E807FF    call 02BA          ;讀扇區(qū)
07C0:03B3 83C40A    add sp, 000A

07C0:03B6 58      pop ax           ;恢復(fù)寄存器
07C0:03B7 5B      pop bx
07C0:03B8 59      pop cx
07C0:03B9 8BE5     mov sp, bp
07C0:03BB 5D      pop bp
07C0:03BC C3      ret

;取出目錄項的起始扇區(qū)和字節(jié)數(shù)
07C0:03BD 50      push ax
07C0:03BE 268B4702   mov ax, es:[bx+02]
07C0:03C2 A39A04    mov [049A], ax
07C0:03C5 268B4704   mov ax, es:[bx+04]
07C0:03C9 A39C04    mov [049C], ax       ;開始邏輯扇區(qū)號
07C0:03CC 268B470A   mov ax, es:[bx+0A]
07C0:03D0 A39E04    mov [049E], ax
07C0:03D3 268B470C   mov ax, es:[bx+0C]
07C0:03D7 A3A004    mov [04A0], ax       ;字節(jié)數(shù)
07C0:03DA 58      pop ax
07C0:03DB C3      ret

;裝載函數(shù),入口為: 文件名地址, 文件名長度, 裝載段地址

07C0:03DC 55      push bp
07C0:03DD 8BEC     mov bp, sp

;讀 CDROM 引導(dǎo)信息
07C0:03DF 6A01     push 0001
07C0:03E1 6A00     push 0000          ;總扇區(qū)數(shù) 00000001
07C0:03E3 680010    push 1000          ;段地址 1000
07C0:03E6 6A10     push 0010
07C0:03E8 6A00     push 0000          ;開始邏輯扇區(qū)號 00000010
07C0:03EA E8CDFE    call 02BA          ;讀扇區(qū)
07C0:03ED 83C40A    add sp, 000A

;取出 root 目錄信息
07C0:03F0 B80010    mov ax, 1000
07C0:03F3 8EC0     mov es, ax
07C0:03F5 26A19E00   mov ax, es:[009E]
07C0:03F9 A39A04    mov [049A], ax
07C0:03FC 26A1A000   mov ax, es:[00A0]
07C0:0400 A39C04    mov [049C], ax       ;開始邏輯扇區(qū)號
07C0:0403 26A1A600   mov ax, es:[00A6]
07C0:0407 A39E04    mov [049E], ax
07C0:040A 26A1A800   mov ax, es:[00A8]
07C0:040E A3A004    mov [04A0], ax       ;讀取字節(jié)數(shù)

07C0:0411 680010    push 1000          ;段地址 1000
07C0:0414 E86AFF    call 0381          ;讀數(shù)據(jù)
07C0:0417 83C402    add sp, 0002

;在 root 目錄中中搜索 "I386"
07C0:041A C706AD049504 mov word ptr [04AD], 0495  ;"I386" 地址
07C0:0420 C606AF0404  mov byte ptr [04AF], 04   ;長度 4
07C0:0425 90      nop
07C0:0426 C606B00401  mov byte ptr [04B0], 01   ;置目錄項標(biāo)記,查找時檢查是否為子目錄
07C0:042B 90      nop
07C0:042C E8C1FD    call 01F0          ;開始搜索
07C0:042F 7234     jb 0465           ;如果沒有找到

;將找到的 "I386" 目錄讀出來
07C0:0431 E889FF    call 03BD          ;取出起始扇區(qū)和字節(jié)數(shù)
07C0:0434 680010    push 1000
07C0:0437 E847FF    call 0381          ;讀取扇區(qū)
07C0:043A 83C402    add sp, 0002

;在 I386 中搜索調(diào)用函數(shù)時的指定文件
07C0:043D B80010    mov ax, 1000
07C0:0440 8EC0     mov es, ax
07C0:0442 8B4608    mov ax, [bp+08]
07C0:0445 A3AD04    mov [04AD], ax       ;文件名地址
07C0:0448 8A4606    mov al , [bp+06]
07C0:044B A2AF04    mov byte ptr [04AF], al   ;文件名長度
07C0:044E C606B00400  mov byte ptr [04B0], 00 ;置目錄項標(biāo)記,查找時檢查是否為文件
07C0:0453 90      nop
07C0:0454 E899FD    call 01F0          ;開始搜索
07C0:0457 720C     jb 0465           ;如果沒有找到

;將找到的指定文件讀出來
07C0:0459 E861FF    call 03BD          ;取出起始扇區(qū)和字節(jié)數(shù)
07C0:045C FF7604    push word ptr [bp+04]
07C0:045F E81FFF    call 0381          ;讀取扇區(qū)
07C0:0462 83C402    add sp, 0002

07C0:0465 5D      pop bp
07C0:0466 C3      ret

;代碼結(jié)束,開始數(shù)據(jù)區(qū)

07C0:0467        DW 0000, 00000       ;保存中斷 08 的原地址
07C0:046B        DW 0000           ;延時計數(shù)器

;此處存放磁盤擴展讀結(jié)構(gòu)

07C0:046D        DB 00            ;結(jié)構(gòu)尺寸
07C0:046E        DB 00            ;保留
07C0:046F        DB 00            ;要讀取的扇區(qū)數(shù)
07C0:0470        DB 00            ;保留
07C0:0471        DW 0000, 0000        ;讀取數(shù)據(jù)的目標(biāo)地址
07C0:0475        DD 00            ;開始邏輯扇區(qū)
07C0:047A        DW 0000           ;保留

07C0:047D        DW 0000           ;段處理標(biāo)記, 為零不需處理

07C0:047E        DB "SETUPLDR.BIN"
07C0:048A        DB "BOOTFIX.BIN"
07C0:0495        DB "I386"

07C0:0499        DB 0000           ;磁盤號

07C0:049A        DW 0000
07C0:049C        DW 0000           ;開始邏輯扇區(qū)號
07C0:049E        DW 0000
07C0:04A0        DW 0000           ;讀取字節(jié)數(shù)

;此處存放讀盤操作的臨時數(shù)據(jù)

07C0:04A2        DW 0000, 0000        ;總扇區(qū)數(shù)
07C0:04A6        DW 0000           ;數(shù)據(jù)區(qū)的段地址
07C0:04A8        DW 0000, 0000        ;開始邏輯扇區(qū)號
07C0:04AC        DW 0000           ;扇區(qū)數(shù)

07C0:04AD        DW 0000           ;搜索字符串地址
07C0:04AF        DW 0000           ;長度
07C0:04B0        DB 00 ;目錄項標(biāo)記,為 1 表示查找子目錄

07C0:04B1        DB 00

07C0:07FE        DB 55, AA

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多