|
我注释的一段BIOS模块
ROMDOS初始化部分
D000:0000 55 DB 55 ;BIOS模块标识
D000:0001 AA DB AA ;BIOS模块标识
D000:0002 20 DB 20 ;模块扇区数
D000:0003 E90203 JMP 0308 ;跳转到初始化入口
延时子过程
D000:00F1 FB STI ;开中断
D000:00F2 50 PUSH AX ;AX入栈
D000:00F3 06 PUSH ES ;ES入栈
D000:00F4 9C PUSHF ;标志寄存器入栈
D000:00F5 6A00 PUSH 00h ;0000h入栈
D000:00F7 07 POP ES ;ES=0000h
D000:00F8 2602266C04 ADD AH,ES:[046C] ;取得时钟滴答并加上AH中的延时值
D000:00FD 263A266C04 CMP AH,ES:[046C] ;判断延时
D000:0102 75F9 JNZ Short 00FD ;未达到延时值转00FDh继续
D000:0104 9D POPF ;标志寄存器出栈
D000:0105 07 POP ES ;ES出栈
D000:0106 58 POP AX ;AX出栈
D000:0107 C3 RET ;返回调用程序
置视频0页及更新光标位置子过程
D000:0108 50 PUSH AX ;AX入栈
D000:0109 53 PUSH BX ;BX入栈
D000:010A B402 MOV AH,02h ;预置视频02h号功能
D000:010C B700 MOV BH,00h ;设置光标到0行
D000:010E CD10 INT 10h ;调用INT10h更新0页光标
D000:0110 5B POP BX ;BX出栈
D000:0111 58 POP AX ;AX出栈
D000:0112 C3 RET ;返回调用程序
置视频0页及光标位置及类型子过程
D000:0113 50 PUSH AX ;AX入栈
D000:0114 53 PUSH BX ;BX入栈
D000:0115 51 PUSH CX ;CX入栈
D000:0116 B403 MOV AH,03h ;预置视频03h号功能
D000:0118 B700 MOV BH,00h ;设置视频0页
D000:011A CD10 INT 10h ;调用INT10h更新0页光标
D000:011C 59 POP CX ;CX出栈
D000:011D 5B POP BX ;BX出栈
D000:011E 58 POP AX ;AX出栈
D000:011F C3 RET ;返回调用程序
显示字符串子过程
D000:0120 60 PUSHA ;通用寄存器全入栈
D000:0121 9C PUSHF ;标志寄存器入栈
D000:0122 53 PUSH BX ;BX入栈
D000:0123 E8EDFF CALL 0113 ;调用置视频0页及光标位置及类型子过程
D000:0126 B409 MOV AH,09h ;预置INT10h的09h号功能
D000:0128 31C9 XOR CX,CX ;CX=0
D000:012A 86CF XCHG CL,BH ;CL与BH交换
D000:012C 80E17F AND CL,7Fh ;CL和7Fh相与
D000:012F 2E8A04 MOV AL,CS:[SI]
D000:0132 3C00 CMP AL,00h
D000:0134 740A JZ Short 0140
D000:0136 CD10 INT 10h
D000:0138 46 INC SI
D000:0139 FEC2 INC DL
D000:013B E8CAFF CALL 0108 ;调用置视频0页及更新光标位置子过程
D000:013E EBEF JMP Short 012F
D000:0140 5B POP BX
D000:0141 80FF80 CMP BH,80h
D000:0144 780F JS Short 0155
D000:0146 9D POPF ;恢复标志寄存器
D000:0147 61 POPA ;恢复全部通用寄存器
以电传模式写方式换行子过程
D000:0148 60 PUSHA ;通用寄存器全入栈
D000:0149 9C PUSHF ;标志寄存器入栈
D000:014A B80D0E MOV AX,0E0Dh ;AL=0Dh,光标回到0列
D000:014D 30DB XOR BL,BL ;BL=0
D000:014F CD10 INT 10h ;执行INT10h调用
D000:0151 B00A MOV AL,0Ah ;光标前进一行
D000:0153 CD10 INT 10h ;执行INT10h调用
D000:0155 9D POPF ;恢复标志寄存器
D000:0156 61 POPA ;恢复全部通用寄存器
D000:0157 C3 RET ;返回调用程序
显示INT13h中断向量子过程 (0158h—01DBh)
D000:0158 50 PUSH AX ;AX入栈
D000:0159 53 PUSH BX ;BX入栈
D000:015A E81100 CALL 016E
D000:015D 87D1 XCHG DX,CX
D000:015F 30DB XOR BL,BL
D000:0161 B83A0E MOV AX,0E3Ah
D000:0164 CD10 INT 10h
D000:0166 E80500 CALL 016E
D000:0169 87D1 XCHG DX,CX
D000:016B 5B POP BX
D000:016C 58 POP AX
D000:016D C3 RET ;返回调用程序
D000:016E 86F2 XCHG DH,DL
D000:0170 E80600 CALL 0179
D000:0173 86F2 XCHG DH,DL
D000:0175 E80100 CALL 0179
D000:0178 C3 RET ;返回调用程序
D000:0179 50 PUSH AX ;AX入栈
D000:017A 52 PUSH DX ;DX入栈
D000:017B 9C PUSHF ;标志寄存器入栈
D000:017C 88D6 MOV DH,DL
D000:017E 80E20F AND DL,0Fh
D000:0181 80E6F0 AND DH,0F0h
D000:0184 C0CE04 ROR DH,04h
D000:0187 E80900 CALL 0193
D000:018A 88D6 MOV DH,DL
D000:018C E80400 CALL 0193
D000:018F 9D POPF ;恢复标志寄存器
D000:0190 5A POP DX
D000:0191 58 POP AX
D000:0192 C3 RET ;返回调用程序
D000:0193 80FE0A CMP DH,0Ah
D000:0196 7203 JB Short 019B
D000:0198 80C607 ADD DH,07h
D000:019B 80C630 ADD DH,30h
D000:019E B40E MOV AH,0Eh
D000:01A0 88F0 MOV AL,DH
D000:01A2 CD10 INT 10h
D000:01A5 60 PUSHA
D000:01A6 1E PUSH DS ;DS入栈
D000:01A7 06 PUSH ES ;ES入栈
D000:01A8 16 PUSH SS ;SS入栈
D000:01A9 0E PUSH CS ;CS入栈
D000:01AA 9C PUSHF ;标志寄存器入栈
D000:01AB B90900 MOV CX,0009h
D000:01AE BEDC01 MOV SI,01DCh
D000:01B1 89E5 MOV BP,SP
D000:01B3 BB0701 MOV BX,0107h
D000:01B6 E867FF CALL 0120 ;调用显示字符串子过程
D000:01B9 B83D0E MOV AX,0E3Dh
D000:01BC 30DB XOR BL,BL
D000:01BE CD10 INT 10h
D000:01C0 368B5600 MOV DX,SS:[BP+00h]
D000:01C4 E8A7FF CALL 016E
D000:01C7 B020 MOV AL,20h
D000:01C9 CD10 INT 10h
D000:01CB 45 INC BP
D000:01CC 45 INC BP
D000:01CD 46 INC SI
D000:01CE 46 INC SI
D000:01CF 46 INC SI
D000:01D0 E2E1 LOOP 01B3
D000:01D2 E873FF CALL 0148 ;调用以电传模式写方式换行子过程
D000:01D5 9D POPF ;恢复标志寄存器
D000:01D6 1F POP DS ;恢复DS
D000:01D7 17 POP SS ;恢复原SS
D000:01D8 07 POP ES ;恢复原ES
D000:01D9 1F POP DS ;恢复原DS
D000:01DA 61 POPA ;恢复全部通用寄存器
D000:01DB C3 RET ;返回调用程序
新的INT13h中断处理程序入口
D000:01F7 9C PUSHF ;标志寄存器入栈
D000:01F8 80FA00 CMP DL,00h ;判断DL值是否为软驱设备号
D000:01FB 7406 JZ Short 0203 ;是软驱设备号转203处理
D000:01FD 9D POPF ;恢复标志寄存器
D000:01FE EA13020000 JMP 0000:0213 ;远转移到0000:0213h,执行原INT13h中断程序
软驱磁盘操作处理
D000:0203 60 PUSHA ;通用寄存器全入栈
D000:0204 1E PUSH DS ;DS入栈
D000:0205 80FC02 CMP AH,02h ;判断是否是读盘操作
D000:0208 7415 JZ Short 021F ;是则转021fh处理
D000:020A 80FC03 CMP AH,03h ;判断是否是写盘操作
D000:020D 7442 JZ Short 0251 ;是则转0251h处理
D000:020F 80FC08 CMP AH,08h ;判断是否是读驱动器参数操作
D000:0212 7452 JZ Short 0266 ;是则转0266h处理
D000:0214 80FC15 CMP AH,15h ;判断是否是读磁盘容量操作
D000:0217 745F JZ Short 0278 ;是则转0278h处理
D000:0219 80C441 ADD AH,41h ;
D000:021C E97100 JMP 0290 ;转到0290h处继续
读盘操作处理
D000:021F 50 PUSH AX ;AX入栈
D000:0220 89DF MOV DI,BX ;DI=INT13h调用数据区偏移址
D000:0222 31F6 XOR SI,SI ;SI=0
D000:0224 80E13F AND CL,3Fh ;屏蔽CL中的柱面位,取得扇区号
D000:0227 FEC9 DEC CL ;CL=CL-1
D000:0229 B81200 MOV AX,0012h ;AX=0012h
D000:022C F6E6 MUL DH ;AL乘以DH (DH是磁头号)
D000:022E 01C6 ADD SI,AX ;SI=SI+AX
D000:0230 B80100 MOV AX,0001h ;AX=0001h
D000:0233 B312 MOV BL,12h ;BL=12h
D000:0235 F6E3 MUL BL ;AL乘以BL
D000:0237 F6E5 MUL CH ;AL乘以CH
D000:0239 01C6 ADD SI,AX ;SI=SI+AX
D000:023B 30ED XOR CH,CH ;CH=0
D000:023D 01CE ADD SI,CX ;SI=SI+CX
D000:023F C1E609 SHL SI,09h ;SI左移9位
D000:0242 81C6FB03 ADD SI,03FBh ;SI=SI+03FBh
D000:0246 0E PUSH CS ;CS入栈
D000:0247 1F POP DS ;DS=CS
D000:0248 59 POP CX ;CX=原AX
D000:0249 C1E109 SHL CX,09h ;CX左移9位
D000:024C F3 REPZ ;重复执行到CX=0
D000:024D A4 MOVSB ;按字节传送
D000:024E E93D00 JMP 028E ;转移到028Eh继续
写盘操作处理
D000:0251 89E5 MOV BP,SP ;BP=SP
D000:0253 368B4618 MOV AX,SS:[BP+18h] ;
D000:0257 0D0100 OR AX,0001h ;
D000:025A 36894618 MOV SS:[BP+18h],AX ;
D000:025E 36C6461103 MOV Byte Ptr SS:[BP+11h],03h ;
D000:0263 E92800 JMP 028E ;
读驱动器参数操作处理
D000:0266 89E5 MOV BP,SP ;
D000:0268 B507 MOV CH,07h ;
D000:026A B112 MOV CL,12h ;
D000:026C 36C6460D01 MOV Byte Ptr SS:[BP+0Dh],01h ;
D000:0271 36894E0E MOV SS:[BP+0Eh],CX ;
D000:0275 E91600 JMP 028E ;
读磁盘容量操作处理
D000:0278 89E5 MOV BP,SP
D000:027A 36C6461101 MOV Byte Ptr SS:[BP+11h],01h ;
D000:027F 36C7460E0000 MOV Word Ptr SS:[BP+0Eh],0000h;
D000:0285 36C7460C7E00 MOV Word Ptr SS:[BP+0Ch],007Eh;
D000:028B E90000 JMP 028E ;
返回调用中断程序处理
D000:028E B42A MOV AH,2Ah ;AH=2Ah
D000:0290 6800B8 PUSH 0B800h ;0B800h入栈
D000:0293 1F POP DS ;DS=0B800h
D000:0294 3E88269E00 MOV DS:[009E],AH ;B800:009E=2Ah
D000:0299 1F POP DS ;恢复原DS
D000:029A 61 POPA ;恢复全部通用寄存器
D000:029B 9D POPF ;恢复标志寄存器
D000:029C CF IRET ;返回调用中断的程序
更换INT13h中断向量
D000:029D 60 PUSHA ;通用寄存器全入栈
D000:029E 06 PUSH ES ;ES入栈
D000:029F 6A00 PUSH 00h ;0000h入栈
D000:02A1 07 POP ES ;ES=0000h
D000:02A2 BE4C00 MOV SI,004Ch ;SI=004Ch,指向INT13h中断向量
D000:02A5 BF1402 MOV DI,0214h ;DI=0214h,指向INT13h中断向量保存处
D000:02A8 268B0C MOV CX,ES:[SI] ;CX=INT13h中断向量偏移址
D000:02AB 26890D MOV ES:[DI],CX ;CX保存到0:0214h
D000:02AE 268B5402 MOV DX,ES:[SI+02h] ;DX=INT13h中断向量段址
D000:02B2 26895502 MOV ES:[DI+02h],DX ;DX保存到0:0216h
D000:02B6 26C645FFEA MOV Byte Ptr ES:[DI-01h],0EAh ;设置JMP指令代码
D000:02BB 26C704F701 MOV Word Ptr ES:[SI],01F7h ;设新的INT13h中断服务程序入口为01F7h
D000:02C0 268C4C02 MOV ES:[SI+02h],CS ;将当前代码段段址作为新的INT13h中断服务程序入口段址
D000:02C4 BEE402 MOV SI,02E4h ;SI=02E4h,设置INT13h中断向量更换成功显示信息的偏移指针
D000:02C7 BB0701 MOV BX,0107h ;设置黑底白字参数
D000:02CA E853FE CALL 0120 ;调用显示字符串子过程显示“INT13h vector has been hooked”
D000:02CD E888FE CALL 0158 ;调用显示原始INT13h中断向量值的子过程
D000:02D0 BE0303 MOV SI,0303h ;SI=0303h,设置显示 -> 符号的偏移指针
D000:02D3 E84AFE CALL 0120 ;调用显示字符串子过程显示“ -> ”符号
D000:02D6 8CCA MOV DX,CS ;DX=CS
D000:02D8 B9F701 MOV CX,01F7h ;CX=01F7h
D000:02DB E87AFE CALL 0158 ;调用显示新INT13h中断向量值的子过程
D000:02DE E867FE CALL 0148 ;调用以电传模式写方式换行子过程
D000:02E1 07 POP ES ;ES出栈
D000:02E2 61 POPA ;恢复全部通用寄存器
D000:02E3 C3 RET ;返回调用程序
D000:02E4 49 4E 54 31 33 68 20 76-65 63 74 6F 72 20 68 61 INT13h vector ha
D000:02F4 73 20 62 65 65 6E 20 68-6F 6F 6B 65 64 20 00 20 s been hooked .
D000:0304 2D 3E 20 00 9C 60 06 1E-8C D0 68 00 40 17 BB FF -> ..`...Ph.@.;.
初始化程序入口
D000:0308 9C PUSHF ;标志寄存器入栈
D000:0309 60 PUSHA ;通用寄存器全入栈
D000:030A 06 PUSH ES ;ES入栈
D000:030B 1E PUSH DS ;DS入栈
D000:030C 8CD0 MOV AX,SS ;AX=SS
D000:030E 680040 PUSH 4000h ;4000h入栈
D000:0311 17 POP SS ;SS=4000h
D000:0312 BBFFFF MOV BX,0FFFFh ;BX=FFFFh
D000:0315 87DC XCHG BX,SP ;SP与BX内容交换
D000:0317 50 PUSH AX ;原栈段址入栈
D000:0318 53 PUSH BX ;原栈偏移指针入栈
D000:0319 6A00 PUSH 00h ;0000h入栈
D000:031B 07 POP ES ;ES=0000h
D000:031C 26813E64000803 CMP Word Ptr ES:[0064],0308h ;比较INT19h中断偏移是否0308h
D000:0323 750C JNZ Short 0331 ;不是转331h处理
D000:0325 8CC8 MOV AX,CS ;AX=CS
D000:0327 2639066600 CMP ES:[0066],AX ;将当前代码段址与INT19h中断段址比较
D000:032C 7503 JNZ Short 0331 ;不是转331h处理
D000:032E E94800 JMP 0379 ;转379h继续执行
启动RomOS的Scroll Lock热键处理
D000:0331 E814FE CALL 0148 ;调用以电传模式写方式换行子过程
D000:0334 BE5400 MOV SI,0054h ;SI指向显示字符串
D000:0337 BB0F81 MOV BX,810Fh ;定义显示页号及属性
D000:033A E8E3FD CALL 0120 ;显示“Press [ScrollLock] to boot ROMOS !”
D000:033D B41E MOV AH,1Eh ;设置延时滴答数
D000:033F E8AFFD CALL 00F1 ;调用延时子过程延时1.5秒
D000:0342 6A00 PUSH 00h ;0000h入栈
D000:0344 07 POP ES ;ES=0000h
D000:0345 26A01704 MOV AL,ES:[0417] ;取组合键当前状态值送到AL
D000:0349 88C4 MOV AH,AL ;AH=AL
D000:034B 2410 AND AL,10h ;AL与10h
D000:034D 3C10 CMP AL,10h ;判断是否已按Scroll Lock键
D000:034F 7408 JZ Short 0359 ;已按croll Lock键,转359h处理
D000:0351 2E8C060000 MOV CS:[0000],ES ;ES保存到本程序首部
D000:0356 E91700 JMP 0370 ;转370h继续执行
实施INT19h中断向量截获
D000:0359 B010 MOV AL,10h ;AL=10h
D000:035B F6D0 NOT AL ;取反AL=EFh
D000:035D 20C4 AND AH,AL ;AH与AL,AH=0
D000:035F 2688261704 MOV ES:[0417],AH ;清除Scroll Lock按键状态
D000:0364 26C70664000803 MOV Word Ptr ES:[0064],0308h ;将本程序初始化入口偏移写入INT19h中断向量
D000:036B 268C0E6600 MOV ES:[0066],CS ;将本程序段址写入INT19h中断向量
D000:0370 5B POP BX ;原栈偏移指针出栈
D000:0371 17 POP SS ;原栈段址出栈
D000:0372 89DC MOV SP,BX ;恢复原栈偏移指针
D000:0374 1F POP DS ;恢复原DS
D000:0375 07 POP ES ;恢复原ES
D000:0376 61 POPA ;原通用寄存器全出栈
D000:0377 9D POPF ;原标志寄存器出栈
D000:0378 CB RETF ;返回BIOS主程序
INT13h中断向量处理
D000:0379 E8CCFD CALL 0148 ;调用以电传模式写方式换行子过程
D000:037C BE7700 MOV SI,0077h ;SI指向显示字符串
D000:037F BB0E81 MOV BX,810Eh ;定义显示页号及属性
D000:0382 E89BFD CALL 0120 ;显示“Welcome to ROMOS ver. 1.02 PCI by Martin Rehak”
D000:0385 B414 MOV AH,14h ;设置延时滴答数
D000:0387 E867FD CALL 00F1 ;调用延时子过程延时0.8秒
D000:038A E810FF CALL 029D ;调用更换INT13h中断向量子过程
D000:038D E861FD CALL 00F1 ;调用延时子过程延时0.8秒
D000:0390 BEA600 MOV SI,00A6h ;SI指向显示字符串
D000:0393 BB0781 MOV BX,8107h ;定义显示页号及属性
D000:0396 E887FD CALL 0120 ;显示“ROMOS has installed virtual ROM DISK drive”
D000:0399 E855FD CALL 00F1 ;调用延时子过程延时0.8秒
D000:039C E8A9FD CALL 0148 ;调用以电传模式写方式换行子过程
D000:039F E803FE CALL 01A5 ;调用未明显示?
D000:03A2 E84CFD CALL 00F1 ;调用延时子过程延时0.8秒
D000:03A5 BED200 MOV SI,00D2h ;SI指向显示字符串
D000:03A8 BB0701 MOV BX,0107h ;定义显示页号及属性
D000:03AB E872FD CALL 0120 ;显示“Bootsector loaded at ”
D000:03AE BA0000 MOV DX,0000h ;DX=0000h
D000:03B1 B9007C MOV CX,7C00h ;CX=7C00h
D000:03B4 E8A1FD CALL 0158 ;调用显示INT13h中断向量子过程
D000:03B7 E88EFD CALL 0148 ;调用以电传模式写方式换行子过程
D000:03BA BEE800 MOV SI,00E8h ;SI指向显示字符串
D000:03BD BB0F81 MOV BX,810Fh ;定义显示页号及属性
D000:03C0 E85DFD CALL 0120 ;显示“Booting!”
D000:03C3 B40A MOV AH,0Ah ;设置延时滴答数 ;
D000:03C5 E829FD CALL 00F1 ;调用延时子过程延时0.5秒
D000:03C8 6A00 PUSH 00h ;0000h入栈
D000:03CA 07 POP ES ;ES=0000h
D000:03CB BE1004 MOV SI,0410h ;SI指向低址数据区设备字
D000:03CE 268A04 MOV AL,ES:[SI] ;取设备字低8位到AL
D000:03D1 B400 MOV AH,00h ;AH=0
D000:03D3 80FC01 CMP AH,01h ;比较AH值是否01h(此处有疑问?)
D000:03D6 7505 JNZ Short 03DD ;转到03DDh继续
D000:03D8 0C40 OR AL,40h ;AL或40h操作
D000:03DA 268804 MOV ES:[SI],AL ;AL送回低址数据区
D000:03DD 680000 PUSH 0000h ;0000h入栈
D000:03E0 07 POP ES ;ES=0000h
D000:03E1 BF007C MOV DI,7C00h ;DI=7C00h
D000:03E4 0E PUSH CS ;CS入栈
D000:03E5 1F POP DS ;DS=CS
D000:03E6 BEFB03 MOV SI,03FBh ;设置源数据指针指向03FBh
D000:03E9 B90002 MOV CX,0200h ;设置传送数据字节数
D000:03EC F3 REPZ ;重复执行
D000:03ED A4 MOVSB ;按字节传送到0:7C00h
D000:03EE 26C606247C00 MOV Byte Ptr ES:[7C24],00h ;对0:7C24h置0
D000:03F4 B200 MOV DL,00h ;DL=0
D000:03F6 EA007C0000 JMP 0000:7C00 ;转移到0:7C00h开始启动RomOS
|
|