被复制过去的代码:
seg000:7C1B ; 读取根据DPT定位DBR并读取,然后转交控制权
seg000:7C1B Fun1 proc far
seg000:7C1B BD BE 07 mov bp, 7BEh
seg000:7C1E B1 04 mov cl, 4
seg000:7C1E
seg000:7C20
seg000:7C20 getDPT_i:
seg000:7C20 38 6E 00 cmp [bp+0], ch ; 读第i个DPT
seg000:7C23 7C 09 jl short isActive ; 找到活动分区
seg000:7C23
seg000:7C25 75 13 jnz short invalid_PT ; Invalid partition table
seg000:7C25
seg000:7C27 83 C5 10 add bp, 10h ; 不是活动分区,则检查下一个DPT
seg000:7C2A E2 F4 loop getDPT_i ; 读第i个DPT
seg000:7C2A
seg000:7C2C CD 18 int 18h ; 遍历所有DPT,都没有符合条件的分区
seg000:7C2C ; 通知BIOS无法引导系统
seg000:7C2C ; 执行这个中断后系统控制权转交给BIOS
seg000:7C2C
seg000:7C2E
seg000:7C2E isActive:
seg000:7C2E 8B F5 mov si, bp ; 找到活动分区
seg000:7C2E
seg000:7C30
seg000:7C30 loc_7C30:
seg000:7C30 83 C6 10 add si, 10h ; 检查剩下的分区是否都是非活动分区
seg000:7C33 49 dec cx
seg000:7C34 74 19 jz short loc_7C4F
seg000:7C34
seg000:7C36 38 2C cmp [si], ch
seg000:7C38 74 F6 jz short loc_7C30 ; 检查剩下的分区是否都是非活动分区
seg000:7C38
seg000:7C3A
seg000:7C3A invalid_PT:
seg000:7C3A A0 B5 07 mov al, ds:7B5h ; Invalid partition table
seg000:7C3A
seg000:7C3D
seg000:7C3D loc_7C3D:
seg000:7C3D B4 07 mov ah, 7 ; 显示错误提示
seg000:7C3F 8B F0 mov si, ax
seg000:7C3F
seg000:7C41
seg000:7C41 loc_7C41:
seg000:7C41 AC lodsb
seg000:7C41
seg000:7C42
seg000:7C42 loc_7C42:
seg000:7C42 3C 00 cmp al, 0
seg000:7C44 74 FC jz short loc_7C42
seg000:7C44
seg000:7C46 BB 07 00 mov bx, 7
seg000:7C49 B4 0E mov ah, 0Eh
seg000:7C4B CD 10 int 10h ; - VIDEO - WRITE CHARACTER AND ADVANCE CURSOR (TTY WRITE)
seg000:7C4B ; AL = character, BH = display page (alpha modes)
seg000:7C4B ; BL = foreground color (graphics modes)
seg000:7C4D EB F2 jmp short loc_7C41
seg000:7C4D
seg000:7C4F ; ---------------------------------------------------------------------------
seg000:7C4F
seg000:7C4F loc_7C4F:
seg000:7C4F 88 4E 10 mov [bp+10h], cl
seg000:7C52 E8 46 00 call readDBR ; 读取[bp]指向的DPT描述的磁盘的DBR
seg000:7C52
seg000:7C55 73 2A jnb short readSuccess
seg000:7C55
seg000:7C57
seg000:7C57 loc_7C57:
seg000:7C57 FE 46 10 inc byte ptr [bp+10h]
seg000:7C5A 80 7E 04 0B cmp byte ptr [bp+4], 0Bh
seg000:7C5E 74 0B jz short loc_7C6B
seg000:7C5E
seg000:7C60 80 7E 04 0C cmp byte ptr [bp+4], 0Ch
seg000:7C64 74 05 jz short loc_7C6B
seg000:7C64
seg000:7C66 A0 B6 07 mov al, ds:7B6h ; Missing operating system
seg000:7C69 75 D2 jnz short loc_7C3D ; 显示错误提示
seg000:7C69
seg000:7C6B
seg000:7C6B loc_7C6B:
seg000:7C6B 80 46 02 06 add byte ptr [bp+2], 6
seg000:7C6F 83 46 08 06 add word ptr [bp+8], 6
seg000:7C73 83 56 0A 00 adc word ptr [bp+0Ah], 0
seg000:7C77 E8 21 00 call readDBR ; 读取[bp]指向的DPT描述的磁盘的DBR
seg000:7C77
seg000:7C7A 73 05 jnb short readSuccess
seg000:7C7A
seg000:7C7C A0 B6 07 mov al, ds:7B6h ; Missing operating system
seg000:7C7F EB BC jmp short loc_7C3D ; 显示错误提示
seg000:7C7F
seg000:7C81 ; ---------------------------------------------------------------------------
seg000:7C81
seg000:7C81 readSuccess:
seg000:7C81 81 3E FE 7D 55 AA cmp ds:word_7DFE, 0AA55h
seg000:7C87 74 0B jz short loc_7C94
seg000:7C87
seg000:7C89 80 7E 10 00 cmp byte ptr [bp+10h], 0
seg000:7C8D 74 C8 jz short loc_7C57
seg000:7C8D
seg000:7C8F A0 B7 07 mov al, ds:7B7h ; Error loading operating system
seg000:7C92 EB A9 jmp short loc_7C3D ; 显示错误提示
seg000:7C92
seg000:7C94 ; ---------------------------------------------------------------------------
seg000:7C94
seg000:7C94 loc_7C94:
seg000:7C94 8B FC mov di, sp
seg000:7C96 1E push ds
seg000:7C97 57 push di
seg000:7C98 8B F5 mov si, bp
seg000:7C9A CB retf ; 故伎重演,转交控制权
seg000:7C9A
seg000:7C9A Fun1 endp ; sp = -4
1. 请注意这里:
mov cl, 4
cmp [bp+0], ch
jl short isActive ; 找到活动分区
我不得不说写这段代码的人有才,我解释下这两句代码的妙处:开始的时候cl=4h,ch=0h,而活动分区的标志应该是80h,二进制是1000 0000。用跳转jl也就是说当标志是小于0的数的时候这个分区是活动分区,标志小于0是什么情况?不就是符合位为1的时候么?80h不就是小于0的么……另外你可能注意到比较的值和循环的控制值都放在CX里,这就是找分区标志却不直接跟80h比的原因:让CX同时做两个用处。
2. 这个函数的作用是:寻找DPT中的活动分区,然后调用readDBR读取该分区的DBR,如果没能找到活动分区或者活动分区有多个则报错。
3. 函数的结尾又用了那招“瞒天过海”实现控制权的转交:
seg000:7C94 8B FC mov di, sp
seg000:7C96 1E push ds
seg000:7C97 57 push di
seg000:7C98 8B F5 mov si, bp
seg000:7C9A CB retf ; 故伎重演,转交控制权