准备工作: linux OS, nasm, bochs.
我的是在虚拟机上运行Fedora,使用的nasm 是2.09. bochs是2.4.6.
于渊的操作系统是从一个boot sector(引导扇区)开始. wiki上这样解释 :
A boot sector is a sector of a hard disk, floppy disk, or similar data storage device that contains machine code for booting programs (usually, but not necessarily, operating systems) stored in other parts of the disk. On an IBM PC compatible machine, the BIOS selects a boot device, then it copies the first sector from the device (which may be a MBR, VBR or any executable code), to address location 0x7C00. On other systems, the process may be quite different.
这里,我就明白了最初的 org 07C00 的 含义。要将系统引导到这里. 因为这里是我们真正操作系统的地址。我查了网上关于07C00的解释:
真正开始执行的引导扇区都会固定装载到07C00处,这里和上面的wiki解释相同. 这可能是IBM-PC的规定. 在X86下,我们的操作系统都遵循这样的规定。下面是我找到的解释:
因为编译器在编译时的地址是从第一行开始用0000h开始相对计算的.假如我们定义一个str: dw "zxy".它的相对地址是0100h,如果我们mov ax str那么就是将0100h传给ax,这在编译后的执行码中是固定的.而引导扇区是使用绝对地址执行的,指令从07c00h处开始执行,那么访问0100h绝对是错误的访问.真实的绝对地址是07c00h+0100h,所以如果你不写org 07c00h,把mov ax str写成mov ax str+07c00h对于传址操作是一样的目的.对于作者的那段程序可以去掉第一行的org 07c00h.把"mov ax,BootMessage"改成"mov ax,BootMessage+07c00h",效果是一样的.
但是如果有大量的传址操作,那就要在每个地方都要+07c00h,那是一件非常头痛的事.所以在第一行加上org 07c00h只是让编译器从相对地址org 07c00h处开始编译第一条指令,那么下面的相对地址被编译加载后就正好和绝对地址吻合.
下面我们看boot的汇编代码:
View Code
上面这段代码很好理解:就是在启动点写入一个字符串,然后进入空循环。如果我们认为这是最初的孩子,想想他刚出生时只会哇哇的哭,还是很像的.不过貌似这个婴儿就哭了一生,嘿嘿,你可以让他接着哭的。比如让蜂鸣器响个不停.
关于Boot Sector 我惨看了下面两篇文章,讲解的很细致,感谢两位的详解:
BootSector 是以 0xAA55作为结束标志.
关于 $:表示 当前行汇编后的地址.
$$:表示 一个节(Section)被汇编后的地址。
最后,讲一个有趣的,我们知道作者的 mov bx,000Ch ;表示 在页号为0(BH=0)黑底红字(BL=0CH,高亮)。我从汇编程序设计IBM—PC一书上查阅了相关内容。
先介绍一下显示器。
(1)显示器通过显卡(显示适配器)连接到计算机上。
(2)单色显示器只能显示黑白两色,彩色显示器能显示多种颜色。
(3)屏幕上各象素的显示信息,存放在显示缓冲区中。
下面是一个内存结构图,来源于网络:
(4)显示器有两种显示方法:
文本方式:将屏幕划分为若干行和列,在每个网格位置上显示象素,一个字符是一个象素。
图像方式:将屏幕划分为m*n的点阵,在每个点的位置显示象素,一个点就是一个象素。
于渊书上介绍的就是在文本模式下画字符:
在文本模式下,对应屏幕上的每个字符,在显示缓冲区中占用两个单元:一个存放ASCII码,一个存放显示属性。
对于属性字节,我找到如下的定义:
---------------------------------------
| 7 | 6 5 4 | 3 2 1 0 |
---------------------------------------
|BL | R G B | I R G B |
| \__背景_/ \____前景______/
| |___ 000 黑 |____________________0000 :黑 1000 : 灰 0010 : 绿 1010 :浅绿
闪烁 010 绿 0100 :红 1100 : 浅红 0111 :灰白 1111:白
0:不闪烁 100 红
1:闪烁 111 白
0CH--00001100:黑底,浅红字.不闪烁.
这下就不单一了,选择你喜欢的颜色,写hello world!吧.

浙公网安备 33010602011771号