📄 硬盘主引导记录.txt
字号:
; 入口参数: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 ;
0000:06E6 50 PUSH AX ;以上四条指令压栈的是扇区LBA号码*2
0000:06E7 06 PUSH ES ;压栈内存目标缓冲区首址段址
0000:06E8 53 PUSH BX ;压栈内存目标缓冲区首址偏移
0000:06E9 51 PUSH CX ;压栈所读扇区数
0000:06EA BE1000 MOV SI,0010 ;注意SI的高8位对应着磁盘地址包的保留字节,必须为0
0000:06ED 56 PUSH SI ;压栈磁盘地址包包长,执行完本条指令一个包已经构造完毕
0000:06EE 8BF4 MOV SI,SP ;规定磁盘地址包偏移指针,这时SP=7BEA
0000:06F0 50 PUSH AX ;保存AX
0000:06F1 52 PUSH DX ;保存DX
0000:06F2 B80042 MOV AX,4200 ;置扩展读功能号
0000:06F5 8A5624 MOV DL,[BP+24] ;取驱动器号,参照0000:0683
; 入口参数:AH=功能号,02为读盘操作;DL=驱动器号
; DS:SI=16字节磁盘地址包——第0字节:包长度(固定为10h);第1字节:保留,必须为0;
; 第2、3字节:所读扇区数;第4~5字节:内存目标缓冲区首址偏移;
; 第6~7字节:内存目标缓冲区首址段址; 第8~15字节:扇区LBA号码
; 出口参数:成功则AH=0;错误则AH=错误代码
0000:06F8 CD13 INT 13 ;执行扩展读操作
0000:06FA 5A POP DX ;
0000:06FB 58 POP AX ;
0000:06FC 8D6410 LEA SP,[SI+10] ;7BEA+10h=7BFA→SP(注意是取偏移而不是取单元内容)
0000:06FF 720A JB 070B ;扩展读不成功转
0000:0701 40 INC AX ;
0000:0702 7501 JNZ 0705 ;
0000:0704 42 INC DX ;AX加1溢出时(比如0FFFFh+1)DX才加1
0000:0705 80C702 ADD BH,02 ;调整BX,使偏移量增加512字节(刚好一扇区)
0000:0708 E2F7 LOOP 0701 ;0701~0708一段代码暂未明白其真实意图!
0000:070A F8 CLC ;
0000:070B 5E POP SI ;
0000:070C C3 RET ;
;
; 0000:070D:中继跳转
0000:070D EB74 JMP 0783 ;
;
; 070F~0745是错误信息!果然是中文Windows98生成的主引导记录,所以我要特别
; “感谢”微软这个傻B,真难为它竟然用中文表述前两个信息!可惜真需显示的时
; 候鬼才能看懂是什么呢!!!我K!——耍弄我们耶!?
; 070F~0718:“分区表无效”中文信息
; 071A~072B:“加载操作系统时出错”中文信息
; 072D~0744:“Missing operating system”英文信息
0000:070F B7 .
0000:0710 D6 C7 F8 B1 ED CE DE D0-A7 00 BC D3 D4 D8 B2 D9 ................
0000:0720 D7 F7 CF B5 CD B3 CA B1-B3 F6 B4 ED 00 4D 69 73 .............Mis
0000:0730 73 69 6E 67 20 6F 70 65-72 61 74 69 6E 67 20 73 sing operating s
0000:0740 79 73 74 65 6D 00 00 00-00 00 00 00 00 00 00 00 system..........
0000:0750 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0760 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0770 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:0780 00 00 00 ...
;
; 0000:0783~0000:0789:控制权移交
0000:0783 8BFC MOV DI,SP ;
0000:0785 1E PUSH DS ;
0000:0786 57 PUSH DI ;构造一个跳转地址
0000:0787 8BF5 MOV SI,BP ;
0000:0789 CB RETF ;交控制权给分区引导记录(0000:7C00)
;
;
0000:078A 00 00 00 00 00 00 ......
0000:0790 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:07A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
;
; 07B8~07BB四个字节的内容用于什么呢?(不同机器此四字节均不同)
; 07BE~07FD为分区表,内含四个分区表项(每表项10h字节)
0000:07B0 00 00 00 00 00 00 00 00-86 D8 00 00 00 00 80 01 ................
0000:07C0 01 00 06 3F 3F FD 3F 00-00 00 41 A0 0F 00 00 00 ...??.?...A.....
0000:07D0 01 FE 05 3F FF FE 80 A0-0F 00 C0 4F 2F 00 00 00 ...?.......O/...
0000:07E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0000:07F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA ..............U.
*1:因为物理扇区号总是从1排列而起
*2:由此可见,就是使用LBA扩展读的功能,主引导记录却限制了分区引导扇区必须在LBA绝对物理扇区
0FFFFFFFFh之前才有可能从该分区引导系统!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -