0000:0676 81FB55AA CMP BX,AA55 ;
0000:067A 7510 JNZ 068C ;扩展INT13h不可用也转
0000:067C F6C101 TEST CL,01 ;测试扩展盘访问是否被支持
0000:067F 740B JZ 068C ;不支持还转
; 因为扩展INT13h方式读盘与标准INT13h方式读盘有很大差别,所以0000:0686处指令修改其后的代码以保证按
; 照扩展读方式读分区引导扇区时能正确跳转到相应的处理程序中。
0000:0681 8AE0 MOV AH,AL ;分区类型→AH
0000:0683 885624 MOV [BP+24],DL ;保存驱动器号→[BP+24]
0000:0686 C706A106EB1E MOV WORD PTR [06A1],1EEB ;修改0000:06A1处代码为"JMP 06C1"
0000:068C 886604 MOV [BP+04],AH ;注意:如果扩展INT13h不能使用则A改分区类型为06,但如果
;扩展INT13h能使用,则仍保持原分区类型不变
0000:068F BF0A00 MOV DI,000A ;★★★其它类型分区由此开始处理。此条指令初始化计数器
0000:0692 B80102 MOV AX,0201 ;AH:读操作,AL:读取1个扇区的内容
0000:0695 8BDC MOV BX,SP ;SP=7C00→BX,指定分区引导记录装入内存的位置偏移
0000:0697 33C9 XOR CX,CX ;CX清零
0000:0699 83FF05 CMP DI,+05 ;注意5
0000:069C 7F03 JG 06A1 ;大于则转去读由分区表指定的分区引导扇区
0000:069E 8B4E25 MOV CX,[BP+25] ;小于则证明所读分区表指定的引导扇区无合法的引导记录,
;改按???再读,毕竟多一种选择多一次机会嘛!;)
; 以下标有①②者请注意它们的地址都是一样的,就是说实际运行中只可能是二者之一,但为了分析之方便,我
; 把两者都列了出来以供对比,阅读时千万别看成是两条指令了啊!
①0000:06A1 034E02 ADD CX,[BP+02] ;获取分区引导扇区所在的柱面号和物理扇区号
②0000:06A1 EB1E JMP 06C1 ;如果分区类型是0Ch、0Eh而且扩展读能使用则执行该指令
;
; 0000:06A4:将可引导分区的分区引导记录装入内存指定区域
; 入口参数:AH=功能号,02为读盘操作;AL=一次读取的扇区数
; ES:BX=读入内存的起始地址
; CH=10位柱面号的低8位;CL:高两位是10位柱面号的高两位,低6位是物理扇区号
; DH=磁头号;DL=驱动器号,最高位(即位7)为0是软盘,为1是硬盘
0000:06A4 CD13 INT 13 ;读分区引导记录到0000:7C00起始的区域
;
;
0000:06A6 7229 JB 06D1 ;不成功转
0000:06A8 BE2D07 MOV SI,072D ;错误信息字符串偏移→SI
0000:06AB 813EFE7D55AA CMP WORD PTR [7DFE],AA55 ;分区引导记录合法吗?
0000:06B1 745A JZ 070D ;合法则转(这是主引导记录唯一的正常出口)
0000:06B3 83EF05 SUB DI,+05 ;不合法则为换读其他扇区做准备
0000:06B6 7FDA JG 0692 ;只有一次换读扇区的机会!
;
; 0000:06B8~0000:06BF:错误预处理
0000:06B8 85F6 TEST SI,SI ;测试SI值是否为0,其意义在于确定该显示哪条信息
0000:06BA 7583 JNZ 063F ;不为0则转错误处理,显示“Missing operating system”
0000:06BC BE1A07 MOV SI,071A ;错误信息字符串偏移→SI
0000:06BF EB8A JMP 064B ;转错误处理,显示“加载操作系统时出错”
;
; 0000:06C1~0000:06CF:整理扩展读所需入口参数,然后调用扩展读子程序
; 这段代码只有在以扩展读方式读取分区引导记录时才有机会获得执行
0000:06C1 98 CBW ;转换字节AL为字AX,执行后,AX中是一次要读的扇区数
0000:06C2 91 XCHG CX,AX ;AX→CX,CX→AX,执行后,CX中是一次要读的扇区数
0000:06C3 52 PUSH DX ;
0000:06C4 99 CWD ;将字AX转换为双字→DX,AX
0000:06C5 034608 ADD AX,[BP+08] ;
0000:06C8 13560A ADC DX,[BP+0A] ;执行后,DX:AX=LBA绝对物理扇区号
0000:06CB E81200 CALL 06E0 ;调用扩展读子程序
0000:06CE 5A POP DX ;
0000:06CF EBD5 JMP 06A6 ;
;
; 0000:06D1~0000:06D8分区引导记录装入失败时的处理
0000:06D1 4F DEC DI ;计数器减1
0000:06D2 74E4 JZ 06B8 ;五次读盘均未成功则转错误处理(注意这时SI=0)
0000:06D4 33C0 XOR AX,AX ;置功能号
0000:06D6 CD13 INT 13 ;复位磁盘系统
0000:06D8 EBB8 JMP 0692 ;再读
;
;
0000:06DA 00 00 80 49 12 00 ...I..
;
; 0000:06E0~0000:070C:使用扩展INT 13h功能读取分区引导记录的子程序
; 调用时,SP=7BFE。这段程序利用压栈寄存器方式构造了一个磁盘地址包,请注意体会。另外,0000:06FC处
; 的一条指令就释放了几乎全部由本段程序占用的栈空间,构思之巧妙,绝对需要我们学习!
; 所以,分析该段程序,一个重点应放在栈的变化上。
0000:06E0 56 PUSH SI ;保存SI——注意,这次压栈并不构造磁盘地址包
0000:06E1 33F6 XOR SI,SI ;清零
0000:06E3 56 PUSH SI ;
0000:06E4 56 PUSH SI ;
0000:06E5 52 PUSH DX &nb
0
顶一下0
踩一下