这章的准备工作要求准备一张空白软盘,大家不用急于准备,暂且往后看。本章主要是理解代码。
代码如下:
org 07C00h ; 告诉编译器程序加载到07C00处
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 ; 结束标志
相信稍有汇编基础的同学都基本懂得这里面写的是什么。下面解释一下几个略显陌生的东西。
为什么是07c00h?
第1行中为什么是07C00h?不是其他的数呢?
这就要从计算机启动开始说起。当计算机电源被打开是,会先进行加点自检(POST),然后寻找启动盘,如果是选择从软盘启动的话,计算机就会检查软盘的0面0磁道1扇区,如果发现它是以0xAA55结束(这里也解释了18行为什么是dw 0xaa55h),则BIOS认为它是一个引导扇区。一旦BIOS发现了引导扇区,就会将其装载到内存的0000:7C00h处,然后跳转入0000:7C00h处将控制权交个这段引导代码。这就是为什么第1行用的是07C00h了。
$和$$是什么东西?
$被称为当前位置计数器,所以"jmp $"是跳转到当前位置,进入无限循环。
$$表示一个section的开始处被汇编后的地址,这里就是07C00h。
想一想$-$$是什么意思呢?
"times 510-($-$$) db 0"是干啥的?
一个正确的引导扇区不仅要以0xaa55h结尾,还要包含一段少于512字节的代码,总长度刚好要是512字节,所以这句是为了凑足512字节的。
jmp -2
如果你执行了这段代码,你会发现进入无限循环时,不断显示的是jmp -2,为什么呢?-2是怎么回事?这就和jmp的机制有关系了,在短跳转中,编译器将jmp的参数编译为相对位移,在执行该代码时,IP中保存的是下一条要执行的代码,就是说是当前代码+2的指令,因此要跳转回当前代码进入无限循环,其相对位移就是-2了。
建议不要去弄什么软盘,也不用去考虑啥U盘、硬盘的,暂且往下看即可。
好了,今天就写到这了。