首先创建文件bootsect.S,这是一个基于汇编语言的源文件。系统的引导就是从这个文件开始的,使用汇编语言与硬件打交道是最方便的。本书选择的汇编编译器是GNU的as,采用的是AT & T语法。编辑文件内容,如代码清单1-1所示。
1 BOOTSEG=0x7c0
2
3 .code16
4 .text
5
6 .global_start
7 _start:
8 jmpl$BOOTSEG,$start2
9
10 start2:
11 movw $BOOTSEG,%ax
12 movw %ax,%ds
13 movw %ax,%es
14 movw %ax,%fs
15 movw %ax,%gs
16
17 movw $msg,%ax
18 movw %ax,%bp
19 movw $0x01301,%ax
20 movw $0x0c,%bx #文字为红色
21 movw $12,%cx #字符串长度
22 movb $0,%dl
23 int $0x010 #通知显卡刷新内容
24
25 loop:
26 jmp loop
27
28 msg:
29 .ascii"Hello World!"
30
31 .org 510
32 boot_flag:
33 .word 0xaa55
在控制台编译bootsect.S,命令如下:
1 #as-o bootsect.o bootsect.S
2 #ld-m elf_x86_64-Ttext 0x0-s--oformat binary-o linux.img bootsect.o
如果一切顺利,则在当前目录下可以看到linux.img文件已创建。将这个文件复制到Bochs的linux011目录下,并在这个目录下执行run.bat文件,则会看到Bochs虚拟机运行起来以后在屏幕上打印了红色的“Hello World!”,如图1-1所示。
图1-1 在屏幕上打印“Hello World!”
如果使用QEMU运行,则需要将linux.img复制到QEMU所在的目录中,然后在QEMU文件路径中打开PowerShell或者cmd,并执行如下命令:
.\qemu-system-i386.exe-boot a-fda linux.img
则同样可以看到,QEMU虚拟机运行起来后在屏幕中打印了红色的“Hello World!”,如图1-2所示。
图1-2 在QEMU中显示“Hello World!”
代码清单1-1第11~15行是设置寄存器的值:将cs寄存器中的值设置到ds和es寄存器。第17~18行是将要打印的字符串的首地址放到bp寄存器。第23行是一条中断触发指令,中断号是0x10,表示和显示器相关的服务。中断功能号保存在ah中。在第19行,ax被赋值为0x1301,那么对应的ah值为0x13。0x13表示在teletype模式下显示字符串。同时al的值为0x01,表示显示输出方式为字符串中含显示字符和显示属性,并且显示后光标位置不变。第20行将0x0c放入bx,在中断号为0x10、功能号为0x13的情况下,bh寄存器存放的是页码,bl寄存器用于设置文字颜色,其中0xc代表红色。第21行将字符串长度送入cx寄存器。第22行表示输出光标的位置,dh表示行号、dl表示列号,这里都为0,表示光标在屏幕的左上角。