分享
 
 
 

NT,2000,XP 的 CDROM 引导扇区代码分析

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

07C0:0000 FAcli ;禁止中断

07C0:0001 33C0xor ax, ax

07C0:0003 8ED0mov ss, ax;初始化运行堆栈,将 SS:SP 指向运行代码前

07C0:0005 BC007Cmov sp, 7C00

07C0:0008 FBsti ;允许中断

07C0:0009 8CC8mov ax, cs

07C0:000B 8ED8mov ds, ax;将 DS 指向 CS 相同地址,此处操作比较浪费,只用了一次

07C0:000D 52push dx ;引导扇区运行时 DX 保存当前引导磁盘号

;下面几条指令用于取得装入偏移地址,由于不能直接对 IP 进行 mov 指令

;所以使用一条 CALL 指令利用堆栈将 IP 取出

07C0:000E E80000call 0011 ;执行一条函数调用指令,从而将下一条指令的地址压入堆栈

07C0:0011 5Epop si;取出刚刚压入的地址

07C0:0012 81EE1100sub si, 0011;减掉偏转地址得到实际的开始偏移

07C0:0016 7412je 002A ;如果偏移为零跳转

;判断装入地址是否为 0000:7C00 如果是则使用远跳转进行地址转换到 0037

07C0:0018 81FE007Ccmp si, 7C00;装入偏移是否为 7C00

07C0:001C 7575jne 0093

07C0:001E 8CC8mov ax, cs;取得装入段地址,此句多余,见 0009

07C0:0020 3D0000cmp ax, 0000;装入段地址是否为 0000

07C0:0023 757Fjne 00A4

07C0:0025 EA3700C007jmp 0037;使用远跳转指令进行地址转换

;判断装入地址是否为 0000 如果是则直接进行运行到 0037

07C0:002A C606AE0133mov byte ptr [01AE], 33 ;修改错误代码为 "3",意义为装载地址错误

07C0:002F 90nop

07C0:0030 8CC8mov ax, cs;多余,同 001E

07C0:0032 3DC007cmp ax, 07C0;装入段地址是否为 07C0

07C0:0035 757Ejne 00B5

;前面这段代码用于解决不同系统装入地址的问题,合法地址为 0000:7C00 或 07C0:0000

;如果地址不正确,则进行错误处理,运行到此处地址应全部转换为 07C0:0037

07C0:0037 8CC8mov ax, cs;取什么取,一定是 07C0 了

07C0:0039 8ED8mov ds, ax;这次才真的有用,见 000B

07C0:003B C606AE0134mov byte ptr [01AE], 34 ;修改错误代码为 "4",意义为非法引导盘

07C0:0040 90nop

07C0:0041 80FA80cmp dl, 80;查看当前引导磁盘号是否小于 80 ,即不是硬盘或 CDROM

07C0:0044 726Fjb 00B5 ;如果是则转移错误处理

07C0:0046 C606AE0135mov byte ptr [01AE], 35 ;修改错误代码为 "5",意义为引导扇区非法或不完整

07C0:004B 90nop

07C0:004C BBFE07mov bx, 07FE;BX 指向引导扇区结尾标志

07C0:004F 8B07mov ax, [bx];取出标志

07C0:0051 3D55AAcmp ax, AA55;是否为 AA55

07C0:0054 755Fjne 00B5;如果不是,则转移错误处理

;装载 BOOTFIX.BIN 并运行,显示 "Press any key to boot from CD"

;如果没有此文件则直接跳过

07C0:0056 5Apop dx;恢复引导磁盘号

07C0:0057 88169904mov [0499], dl;保存磁盘号至数据区

07C0:005B 688A04push 048A ;"BOOTFIX.BIN" 文件名的地址

07C0:005E 6A0Bpush 000B ;文件名长度为 11

07C0:0060 680020push 2000 ;装载起始段地址 2000

07C0:0063 E87603call 03DC ;调用装载函数

07C0:0066 0F820F00jb 0079 ;如果不成功则直接跳过

07C0:006A 60pusha

07C0:006B 1Epush ds

07C0:006C 06push es ;保存当前运行现场

07C0:006D 8A169904mov dl, [0499];取出当前引导磁盘号

07C0:0071 9A00000020call 2000:0000;运行刚刚装载的 BOOTFIX.BIN

07C0:0076 07pop es

07C0:0077 1Fpop ds

07C0:0078 61popa;恢复运行现场

;装载 SETUPLDR.BIN 并运行

07C0:0079 687E04push 047E ;"SETUPLDR.BIN" 文件名的地址

07C0:007C 6A0Cpush 000C ;文件名长度为 12

07C0:007E 680020push 2000 ;装载起始段地址 2000

07C0:0081 E85803call 03DC ;调用装载函数

07C0:0084 0F823500jb 00BD ;如果不成功则转错误处理

07C0:0088 8A169904mov dl, [0499];取出当前引导磁盘号

07C0:008C 33C0xor ax, ax

07C0:008E 680020push 2000

07C0:0091 50push ax ;在堆栈中制造 2000:0000 的返回地址

07C0:0092 CBretf;转移到 2000:0000 运行刚装载的 SETUPLDR.BIN

;由 07C0:001C 转此

07C0:0093 56push si

07C0:0094 8BDEmov bx, si

07C0:0096 81C3AE01add bx, 01AE;计算偏移

07C0:009A C60731mov byte ptr [bx], 31 ;修改错误代码为 "1",意义为引导段地址错误

07C0:009D 81C68A01add si, 018A;"CDBOOT: Cannotboot from CD - Code: "

07C0:00A1 EB2Ajmp 00CD;显示并重新引导

07C0:00A3 90nop

;由 07C0:0023 转此

07C0:00A4 56push si

07C0:00A5 8BDEmov bx, si

07C0:00A7 81C3AE01add bx, 01AE

07C0:00AB C60732mov byte ptr [bx], 32 ;修改错误代码为 "2",意义为引导偏移地址错误

07C0:00AE 81C68A01add si, 018A;"CDBOOT: Cannotboot from CD - Code: "

07C0:00B2 EB19jmp 00CD;显示并重新引导

07C0:00B4 90nop

;由 07C0:0035, 07C0:0044, 07C0:0054 转此

07C0:00B5 6A00push 0000

07C0:00B7 BE8A01mov si, 018A;"CDBOOT: Cannotboot from CD - Code: "

07C0:00BA EB11jmp 00CD;显示并重新引导

07C0:00BC 90nop

;由 07C0:0084 转此

07C0:00BD 6A00push 0000

07C0:00BF BEB201mov si, 01B2;"CDBOOT: Couldn't find NTLDR"

07C0:00C2 EB09jmp 00CD;显示并重新引导

07C0:00C4 90nop

;由 07C0:0367 转此

07C0:00C5 6A00push 0000

07C0:00C7 BED001mov si, 01D0;"CDBOOT: Memoryoverflow error"

07C0:00CA EB01jmp 00CD;显示并重新引导

07C0:00CC 90nop

;显示并重新引导,si 中为要显示的信息

07C0:00CD E80400call 00D4 ;显示 si 中的信息

07C0:00D0 5Epop si;恢复引导扇区被装载的偏移地址

07C0:00D1 EB12jmp 00E5;开始错误处理

07C0:00D3 90nop

;显示信息函数,入口:

;si: 信息起始地址, 0 结尾

07C0:00D4 AClodsb ;取一个字符

07C0:00D5 0AC0or al , al;是否结尾

07C0:00D7 0F840900je 00E4

07C0:00DB B40Emov ah, 0E

07C0:00DD BB0700mov bx, 0007

07C0:00E0 CD10int 10;显示

07C0:00E2 EBF0jmp 00D4

07C0:00E4 C3ret

;错误处理,此间地址可能因装载地址不同有所不同,所以使用 si 作为基础地址进行地址运算

;首先延时 0024 次时钟中断,即 36 * 55 = 1980 ms,大约两秒

07C0:00E5 C7846B042400mov word ptr [si+046B], 0024 ;设定延时计数器为 0024

07C0:00EB FAcli

07C0:00EC 06push es

07C0:00ED 33C0xor ax, ax

07C0:00EF 8EC0mov es, ax;es 指向中断地址表

07C0:00F1 BB2000mov bx, 0020;bx 指向中断 08 的偏移

07C0:00F4 268B07mov ax, es:[bx]

07C0:00F7 89846704mov [si+0467], ax

07C0:00FB 268B4702mov ax, es:[bx+02]

07C0:00FF 89846904mov [si+0469], ax ;保存原中断 08 的地址到 0467

07C0:0103 268937mov es:[bx], si

07C0:0106 2681076D01add word ptr es:[bx], 016D

07C0:010B 268C4F02mov es:[bx+02], cs;将中断 08 指向 07C0:016B

07C0:010F 07pop es

07C0:0110 FBsti

07C0:0111 83BC6B0400cmp word ptr [si+046B], 0000 ;查看计数器是否结束

07C0:0116 75F9jne 0111

07C0:0118 FAcli

07C0:0119 06push es

07C0:011A 33C0xor ax, ax

07C0:011C 8EC0mov es, ax

07C0:011E BB2000mov bx, 0020

07C0:0121 8B846704mov ax, [si+0467]

07C0:0125 268907mov es:[bx], ax

07C0:0128 8B846904mov ax, [si+0469]

07C0:012C 26894702mov es:[bx+02], ax;恢复刚才保存的中断 08 的地址

07C0:0130 07pop es

07C0:0131 FBsti

;将引导扇区代码移动到 2000:0000,以便在 07C0:0000 装载新的引导扇区

07C0:0132 1Epush ds

07C0:0133 06push es

07C0:0134 B80020mov ax, 2000

07C0:0137 8EC0mov es, ax

07C0:0139 8CC8mov ax, cs

07C0:013B 8ED8mov ds, ax

07C0:013D 33FFxor di, di

07C0:013F B90008mov cx, 0800

07C0:0142 F3repz

07C0:0143 A4movsb

07C0:0144 07pop es

07C0:0145 1Fpop ds

07C0:0146 EA4B010020jmp 2000:014B ;转移到

;在 07C0:0000 装载硬盘的引导扇区此段代码执行时已经被移动到 2000:014B

07C0:014B 06push es

07C0:014C B8C007mov ax, 07C0

07C0:014F 8EC0mov es, ax

07C0:0151 BB0000mov bx, 0000

07C0:0154 B80102mov ax, 0201

07C0:0157 B90100mov cx, 0001

07C0:015A BA8000mov dx, 0080

07C0:015D CD13int 13

07C0:015F 0F830200jnb 0165

07C0:0163 EBFEjmp 0163;如果装载失败,则死循环

07C0:0165 07pop es

07C0:0166 B280mov dl, 80

07C0:0168 EA007C0000jmp 0000:7C00 ;转移到硬盘引导扇区处理

;新的中断 08 处理程序,每次中断产生都将计数器减一,减至零为止

07C0:016D 9Cpushf

07C0:016E FAcli

07C0:016F 2E83BC6B0400cmp word ptr cs:[si+046B], 0000 ;计数器是否为零

07C0:0175 0F840500je 017E

07C0:0179 2EFF8C6B04dec word ptr cs:[si+046B] ;不为零则减一

07C0:017E 9Dpopf

07C0:017F 2EFFB46904push word ptr cs:[si+0469]

07C0:0184 2EFFB46704push word ptr cs:[si+0467];将原中断地址压入堆栈

07C0:0189 CBretf;转入系统中断处理程序继续处理

;错误提示信息

07C0:018A DB "CDBOOT: Cannotboot 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: Memoryoverflow error", 0D, 0A, 00

;以下为前面的代码中使用的函数

;从刚刚读取的目录中搜索指定的字符串

;这段的作用就是在整个目录中查找指定的文件

;查找的时候考虑了远指针的最小化偏移

;并且考虑了跨段的查找问题

;纯粹算法,没什么逻辑,所以比较烦琐,也比较无聊

;如果想了解的话可以自己查 iso9660 里面有关目录项的内容去一行行详细分析

07C0:01F0 C606B10400mov byte ptr [04B1], 00 ;

07C0:01F5 90nop

07C0:01F6 8B0E9E04mov cx, [049E];取出读取的字符数低位

07C0:01FA FCcld

07C0:01FB 33DBxor bx, bx;es:bx 指向目录开始

07C0:01FD 33D2xor dx, dx

07C0:01FF 8B36AD04mov si, [04AD];要搜索的字符串的地址

07C0:0203 268A17mov dl, es:[bx] ;取该目录项长度

07C0:0206 80FA00cmp dl, 00;如果长度为零,则跳过该项

07C0:0209 0F843B00je 0248

07C0:020D 8BC3mov ax, bx

07C0:020F 052100add ax, 0021;加 21H 指向目录项中文件名

07C0:0212 8BF8mov di, ax

07C0:0214 51push cx

07C0:0215 33C9xor cx, cx

07C0:0217 8A0EAF04mov cl , [04AF] ;cx 为字符串长度

07C0:021B F3repz

07C0:021C A6cmpsb ;比较字符串

07C0:021D 59pop cx

07C0:021E 0F846F00je 0291 ;如果相同

07C0:0222 3BD1cmp dx, cx;比较目录项长度与总长度的低位

07C0:0224 0F833700jnb 025F ;如果不足则处理总长度高位

07C0:0228 2BCAsub cx, dx;从总长度低位中减掉当前目录项长度

07C0:022A 803EB10401cmp byte ptr [04B1], 01

07C0:022F 0F841A00je 024D

07C0:0233 03D3add dx, bx ;偏移地址加本目录项指向下一目录项

07C0:0235 8BDAmov bx, dx

07C0:0237 83E30Fand bx, 000F

07C0:023A 51push cx

07C0:023B B104mov cl, 04

07C0:023D D3EAshr dx, cl

07C0:023F 59pop cx

07C0:0240 8CC0mov ax, es

07C0:0242 03C2add ax, dx

07C0:0244 8EC0mov es, ax;最小化远指针偏移

07C0:0246 EBB7jmp 01FF

07C0:0248 BA0100mov dx, 0001 ;设定长度为一,直接进入下次比较

07C0:024B EBD5jmp 0222

07C0:024D 41inc cx

07C0:024E C606B10400mov byte ptr [04B1], 00

07C0:0253 90nop

07C0:0254 EBDDjmp 0233

07C0:0256 C606B10401mov byte ptr [04B1], 01

07C0:025B 90nop

07C0:025C EB29jmp 0287

07C0:025E 90nop

07C0:025F 833EA00400cmp word ptr [04A0], 0000 ;总长度高位是否为零

07C0:0264 0F850200jne 026A ;如果不为零则继续处理

07C0:0268 F9stc ;没有找到

07C0:0269 C3ret

07C0:026A 832EA00401sub word ptr [04A0], 0001 ;高位减一

07C0:026F 03DAadd bx, dx ;偏移地址加本目录项指向下一目录项

07C0:0271 53push bx

07C0:0272 51push cx

07C0:0273 B104mov cl, 04

07C0:0275 D3EBshr bx, cl

07C0:0277 59pop cx

07C0:0278 8CC0mov ax, es

07C0:027A 03C3add ax, bx

07C0:027C 8EC0mov es, ax;最小化远指针偏移

07C0:027E 5Bpop bx

07C0:027F 83E30Fand bx, 000F

07C0:0282 2BD1sub dx, cx

07C0:0284 74D0je 0256

07C0:0286 4Adec dx

07C0:0287 B8FFFFmov ax, FFFF

07C0:028A 2BC2sub ax, dx

07C0:028C 8BC8mov cx, ax ;得到新的总长度的地位剩余值

07C0:028E E96EFFjmp 01FF ;继续查找

07C0:0291 803EB00401cmp byte ptr [04B0], 01 ;此次查找是否是子目录

07C0:0296 0F840A00je 02A4 ;如果是子目录则转子目录属性检查

07C0:029A 26F6471902test byte ptr es:[bx+19], 02 ;查看目录属性是否为文件

07C0:029F 7581jne 0222 ;如果不是继续查找

07C0:02A1 EB0Ajmp 02AD

07C0:02A3 90nop

07C0:02A4 26F6471902test byte ptr es:[bx+19], 02 ;查看目录属性是否为子目录

07C0:02A9 0F8475FFje 0222 ;如果不是则继续查找

07C0:02AD A0AF04mov al, [04AF]

07C0:02B0 26384720cmp es:[bx+20], al ;比较文件名长度

07C0:02B4 0F856AFFjne 0222 ;不相同则继续比较

07C0:02B8 F8clc ;清除标记,查找成功

07C0:02B9 C3ret

;下面的几个函数使用了类 C 的参数传递方法

;所以大家看到了熟悉的 push bp / mov bp, sp 指令对

;但是显然作者对高级语言函数堆栈组织不很熟悉,

;连函数结尾的 mov sp, bp 也生搬了过来

;这条指令是高级语言用来释放自动局部变量的

;而这里的几个函数则根本没有使用局部变量

;其实如果使用局部变量的话这里的几个函数会比较好看一些,

;我指的是看起来比较象 C 的反汇编代码

;呵呵

;读指定扇区到内存,使用扩展磁盘读写

;考虑到 DOS 下的 64K 数据段的限制, 读操作是循环执行的.

07C0:02BA 55push bp

07C0:02BB 8BECmov bp, sp

07C0:02BD 53push bx

07C0:02BE 56push si

07C0:02BF 52push dx

07C0:02C0 50push ax ;保存寄存器

07C0:02C1 BB6D04mov bx, 046D;bx 指向扩展磁盘读结构

07C0:02C4 C60710mov byte ptr [bx], 10

07C0:02C7 C6470100mov byte ptr [bx+01], 00

07C0:02CB C6470300mov byte ptr [bx+03], 00

07C0:02CF C747040000mov word ptr [bx+04], 0000

07C0:02D4 C7470C0000mov word ptr [bx+0C], 0000

07C0:02D9 C7470E0000mov word ptr [bx+0E], 0000;全部清除

;将调用参数复制到临时数据区

07C0:02DE 8B460Cmov ax, [bp+0C]

07C0:02E1 A3A204mov [04A2], ax

07C0:02E4 8B460Amov ax, [bp+0A]

07C0:02E7 A3A404mov [04A4], ax;读盘总扇区数,32 位,分两次处理

07C0:02EA 8B4608mov ax, [bp+08]

07C0:02ED A3A604mov [04A6], ax;数据区的段地址

07C0:02F0 8B4606mov ax, [bp+06]

07C0:02F3 A3A804mov [04A8], ax

07C0:02F6 8B4604mov ax, [bp+04]

07C0:02F9 A3AA04mov [04AA], ax;开始逻辑扇区号,32位

;以上将调用时传递的参数保存在数据区以便使用,

;其实大可不必,既然用了类 C 的参数传递,

;那么完全可以直接使用这些实参当变量用

07C0:02FC 813EA4040000cmp word ptr [04A4], 0000

07C0:0302 0F851900jne 031F

07C0:0306 813EA2042000cmp word ptr [04A2], 0020

07C0:030C 0F8F0F00jg 031F ;总扇区数是否小于 20

;保证每次读取的数据量不超过 64K.

;如果总扇区数小于 20H ,即 20H * 800H = 10000H, 正好是 64K 一个数据段的尺寸

;注意,这里处理的是 CDROM 的扇区, 所以扇区大小是 800H, 2048 字节

07C0:0310 C6067D0400mov byte ptr [047D], 00 ;清除标记标示不需段处理

07C0:0315 90nop

07C0:0316 A1A204mov ax, word ptr [04A2]

07C0:0319 A2AC04mov byte ptr [04AC], al ;直接读取总扇区数

07C0:031C EB0Djmp 032B

07C0:031E 90nop

07C0:031F C6067D0401mov byte ptr [047D], 01 ;置标记标示需要段处理

07C0:0324 90nop

07C0:0325 C606AC0420mov byte ptr [04AC], 20 ;每次固定读取 20 个扇区,即 64K 数据

07C0:032A 90nop

07C0:032B A0AC04mov al, [04AC]

07C0:032E 884702mov [bx+02], al ;扇区数

07C0:0331 A1A604mov ax, [04A6]

07C0:0334 894706mov [bx+06], ax ;数据区的段地址

07C0:0337 A1A804mov ax, [04A8]

07C0:033A 894708mov [bx+08], ax

07C0:033D A1AA04mov ax, [04AA]

07C0:0340 89470Amov [bx+0A], ax ;开始逻辑扇区号

07C0:0343 BE6D04mov si, 046D

07C0:0346 B442mov ah, 42

07C0:0348 8A169904mov dl, [0499];取出引导磁盘号

07C0:034C CD13int 13;操作

07C0:034E 803E7D0401cmp byte ptr [047D], 01 ;是否还需要读取?

07C0:0353 0F852200jne 0379

07C0:0357 832EA20420sub word ptr [04A2], 0020

07C0:035C 831EA40400sbb word ptr [04A4], 0000 ;总扇区数减掉 20

07C0:0361 8106A6040010add word ptr [04A6], 1000 ;数据段地址减掉 1000, 指向下一个 64K.

07C0:0367 0F825AFDjb 00C5 ;如果溢出则转错误

07C0:036B 8106A8042000add word ptr [04A8], 0020

07C0:0371 8116AA040000adc word ptr [04AA], 0000 ;开始逻辑扇区号加 20

07C0:0377 EB83jmp 02FC;开始下一次循环读取

07C0:0379 58pop ax;恢复寄存器

07C0:037A 5Apop dx

07C0:037B 5Epop si

07C0:037C 5Bpop bx

07C0:037D 8BE5mov sp, bp

07C0:037F 5Dpop bp

07C0:0380 C3ret

;从指定扇区开始读取指定的字节数到内存

;调用 02BA 完成读取

07C0:0381 55push bp

07C0:0382 8BECmov bp, sp

07C0:0384 51push cx

07C0:0385 53push bx

07C0:0386 50push ax

;将字节数转换为逻辑扇区数,不足一个扇区按照一个扇区计算

07C0:0387 B10Bmov cl, 0B

07C0:0389 8B1EA004mov bx, [04A0]

07C0:038D A19E04mov ax, [049E]

07C0:0390 0FADD8shrd ax, bx, cl

07C0:0393 D3EBshr bx, cl;将 bx:ax 右移 11 位,即除 2048

07C0:0395 F7069E04FF07test word ptr [049E], 07FF;低位是否为零

07C0:039B 7406je 03A3

07C0:039D 050100add ax, 0001

07C0:03A0 83D300adc bx, 0000;不是则加一

07C0:03A3 50push ax

07C0:03A4 53push bx ;总扇区数

07C0:03A5 FF7604push word ptr [bp+04] ;段地址

07C0:03A8 FF369A04push word ptr [049A]

07C0:03AC FF369C04push word ptr [049C];开始逻辑扇区号

07C0:03B0 E807FFcall 02BA ;读扇区

07C0:03B3 83C40Aadd sp, 000A

07C0:03B6 58pop ax;恢复寄存器

07C0:03B7 5Bpop bx

07C0:03B8 59pop cx

07C0:03B9 8BE5mov sp, bp

07C0:03BB 5Dpop bp

07C0:03BC C3ret

;取出目录项的起始扇区和字节数

07C0:03BD 50push ax

07C0:03BE 268B4702mov ax, es:[bx+02]

07C0:03C2 A39A04mov [049A], ax

07C0:03C5 268B4704mov ax, es:[bx+04]

07C0:03C9 A39C04mov [049C], ax;开始逻辑扇区号

07C0:03CC 268B470Amov ax, es:[bx+0A]

07C0:03D0 A39E04mov [049E], ax

07C0:03D3 268B470Cmov ax, es:[bx+0C]

07C0:03D7 A3A004mov [04A0], ax;字节数

07C0:03DA 58pop ax

07C0:03DB C3ret

;装载函数,入口为: 文件名地址, 文件名长度, 装载段地址

07C0:03DC 55push bp

07C0:03DD 8BECmov bp, sp

;读 CDROM 引导信息

07C0:03DF 6A01push 0001

07C0:03E1 6A00push 0000 ;总扇区数 00000001

07C0:03E3 680010push 1000 ;段地址 1000

07C0:03E6 6A10push 0010

07C0:03E8 6A00push 0000 ;开始逻辑扇区号 00000010

07C0:03EA E8CDFEcall 02BA ;读扇区

07C0:03ED 83C40Aadd sp, 000A

;取出 root 目录信息

07C0:03F0 B80010mov ax, 1000

07C0:03F3 8EC0mov es, ax

07C0:03F5 26A19E00mov ax, es:[009E]

07C0:03F9 A39A04mov [049A], ax

07C0:03FC 26A1A000mov ax, es:[00A0]

07C0:0400 A39C04mov [049C], ax;开始逻辑扇区号

07C0:0403 26A1A600mov ax, es:[00A6]

07C0:0407 A39E04mov [049E], ax

07C0:040A 26A1A800mov ax, es:[00A8]

07C0:040E A3A004mov [04A0], ax;读取字节数

07C0:0411 680010push 1000 ;段地址 1000

07C0:0414 E86AFFcall 0381 ;读数据

07C0:0417 83C402add sp, 0002

;在 root 目录中中搜索 "I386"

07C0:041A C706AD049504mov word ptr [04AD], 0495 ;"I386" 地址

07C0:0420 C606AF0404mov byte ptr [04AF], 04 ;长度 4

07C0:0425 90nop

07C0:0426 C606B00401mov byte ptr [04B0], 01 ;置目录项标记,查找时检查是否为子目录

07C0:042B 90nop

07C0:042C E8C1FDcall 01F0 ;开始搜索

07C0:042F 7234jb 0465 ;如果没有找到

;将找到的 "I386" 目录读出来

07C0:0431 E889FFcall 03BD ;取出起始扇区和字节数

07C0:0434 680010push 1000

07C0:0437 E847FFcall 0381 ;读取扇区

07C0:043A 83C402add sp, 0002

;在 I386 中搜索调用函数时的指定文件

07C0:043D B80010mov ax, 1000

07C0:0440 8EC0mov es, ax

07C0:0442 8B4608mov ax, [bp+08]

07C0:0445 A3AD04mov [04AD], ax;文件名地址

07C0:0448 8A4606mov al , [bp+06]

07C0:044B A2AF04mov byte ptr [04AF], al ;文件名长度

07C0:044E C606B00400mov byte ptr [04B0], 00 ;置目录项标记,查找时检查是否为文件

07C0:0453 90nop

07C0:0454 E899FDcall 01F0 ;开始搜索

07C0:0457 720Cjb 0465 ;如果没有找到

;将找到的指定文件读出来

07C0:0459 E861FFcall 03BD ;取出起始扇区和字节数

07C0:045C FF7604push word ptr [bp+04]

07C0:045F E81FFFcall 0381 ;读取扇区

07C0:0462 83C402add sp, 0002

07C0:0465 5Dpop bp

07C0:0466 C3ret

;代码结束,开始数据区

07C0:0467 DW 0000, 00000;保存中断 08 的原地址

07C0:046B DW 0000 ;延时计数器

;此处存放磁盘扩展读结构

07C0:046D DB 00 ;结构尺寸

07C0:046E DB 00 ;保留

07C0:046F DB 00 ;要读取的扇区数

07C0:0470 DB 00 ;保留

07C0:0471 DW 0000, 0000 ;读取数据的目标地址

07C0:0475 DD 00 ;开始逻辑扇区

07C0:047A DW 0000 ;保留

07C0:047D DW 0000 ;段处理标记, 为零不需处理

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 ;开始逻辑扇区号

07C0:049E DW 0000

07C0:04A0 DW 0000 ;读取字节数

;此处存放读盘操作的临时数据

07C0:04A2 DW 0000, 0000 ;总扇区数

07C0:04A6 DW 0000 ;数据区的段地址

07C0:04A8 DW 0000, 0000 ;开始逻辑扇区号

07C0:04AC DW 0000 ;扇区数

07C0:04AD DW 0000 ;搜索字符串地址

07C0:04AF DW 0000 ;长度

07C0:04B0 DB 00 ;目录项标记,为 1 表示查找子目录

07C0:04B1 DB 00

07C0:07FE DB 55, AA

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有