上一节虽然可以让我们启动一个不依赖于系统的“程序”,可实在太简单了,简直是一个不能说也不能动的“死鸭”。从本节开始,我们将在其中不断添加新功能,让它一步步活起来,从此以后,我叫它“笨鸭”(stupid duck)。本节,我们要做两件事:1、让我们的系统可以输出一行英文“welcome to stupid duck!”;2、履行MBR的职责,检查引导区的最后两个字节是否为55AA。
在没有任何系统的情况下,要实现屏显可借助的技术包括直接向显卡RAM中写入数据、调用int10显示等。在下面的程序中,主要利用int10完成屏幕显示:
在本节,我们顺便以二进制的方式讨论下机器语言
10111001 0000000000000000;;
1011:mov 立即数到寄存器;1:16位;001:CX;
00000000 00000000:立即数
7c00: mov cx,0 B90000
10001110 11011001;;
10001110:mov 到段寄存器;
11:寄存器到段寄存器;0:固定; 11:DS寄存器:001:CX寄存器
7c03: mov ds,cx 8ED9
10110100 00001110
1011:mov 立即数到寄存器;0:8位;100:AH;
00001110:立即数
7c05: movah,e B40E
10110011 00001111
1011:mov 立即数到寄存器;0:8位;011:BL;
00001111:立即数
7c07: mov bl,f B30F
10111110 00100110 01111100
1011:mov 立即数到寄存器;1:16位;110:SI;
00100110 01111100:立即数
7c09: mov si,7c26 BE267C
10001010 00000100
100010:mov 存储器-寄存器,寄存器-寄存器寻址;1:寄存器用于目的;0:8位;
00:无偏移量存储器寻址;000:AL;100:[SI]
7c0c: mov al,[si] 8A04
01000110
01000: inc寄存器自增(16位) 110:SI
7c0e: inc si 46
00111000 11101000.
001110:cmp 寄存器-寄存器、存储器 0:源寄存器 0:字节
11:寄存器-寄存器 101:CH; 000:AL
7c0f: cmp al,ch 38E8
01110100 00000100
01110100:ZF为1跳转
00000100:jZ偏移量
7c11: jz $+4 = 7c17 7404
11001101 00010000
1100110:int 中断; 1:非3号中断
00010000:10号中断
7c13: int 10 CD10
11101011 11110101
11101011:jmp 段内短转移
11110101:偏移量
7c15: jmp $-b=7c0c EBF5
10001011 00001110 11111110 01111101
100010:mov 存储器到寄存器;1:目的寄存器; 1:字操作;
00001110:00:无偏移;001:CX;110:D16(DS)
11111110 01111101:内存地址 7DFE
7c1b: movcx,[7dfe] 8B0EFE7D
10000001 11111001 01010101 10101010
100000** **111:cmp 立即数与寄存器存储器 0:非符号扩展 1:字操作
11:寄存器 001:CX
7c1b: cmp,cx,aa55 81F955AA
01110101 00000011
01110101: ZF为0跳转
00000011:偏移量
7c1f: jnz$+3=7c24 7503
11110100
11110100:hlt 停机,等待中断唤醒
7c21: hlt F4
11101011 11111101
11101011:jmp 段内短转移
11111101:偏移量
7c22: jmp $-3=7c21 EBFD
11001101 00011000
1100110:int 中断; 1:非3号中断
00011000:10号中断
7c24: int 18 CD18
7DFE-7DFF 55AA
7C26-7c3F 0A0D7765 6C63 6F6D 6520-746F 2073 7475 7069-6420 6475 636b 2100
在本节中,我们使用debug工具中的-n –w 命令将上述代码暂时保存到DOS下,以方便下次修改。