这一章内容主要是最基本的介绍和了解,但是有一个关键地方需要注意,就是引导扇区的问题。
书上写道“我们知道,当计算机电源被打开时,它会先进行加电自检(POST),然后寻找启动盘,如果是选择从软盘启动,计算机就会检查软盘的0面0磁道1扇区,如果发现它以0xAA55结束,则BIOS认为它是一个引导扇区。”
书上给出的第一段示例代码如下:
org 07c00h ; 告诉编译器程序加载到7c00处
mov ax, cs
mov ds, ax
mov es, ax
call DispStr ; 调用显示字符串例程
jmp $ ; 无限循环
DispStr:
mov ax, BootMessage
mov bp, ax ; ES:BP = 串地址
mov cx, 16 ; CX = 串长度
mov ax, 01301h ; AH = 13, AL = 01h
mov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
mov dl, 0
int 10h ; 10h 号中断
ret
BootMessage: db "Hello, OS world!"
times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 结束标志
最后用0xaa55填充了第511和512个字节,使得该段代码可以成为一个引导扇区,但是,这也给后面的章节留下了一个小问题。我在进行后续章节学习的时候,发现虚拟机bochs有时候会提示“fatal no bootable device”的错误,查阅资料后发现是因为BIOS找不到引导扇区,那么,为什么书上的操作就可以正确运行呢?
这里有一个细节在于,书上第三章开始用到的a.img镜像都是从第一章拷贝的,因此,其结尾均是0xaa55,例如,将pmtest1.bin文件写入a.img的时候,只会修改前面的字节,而结尾的标志0xaa55不会改变。而我在做实验的时候,是新创建了a.img镜像,因此,不可以作为引导扇区使用。解决方法是在代码后面进行填充,在后面第三章会有更详细的描述,包括对二进制代码的分析。