动手写一个最小的“操作系统”
最小的操作系统代码
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 ; 结束标志
编译
用nasm命令编译
nasm boot.asm –o boot.bin
nasm -f bin boot.asm -o boot.bin
写入磁盘
sudo dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc
在进行这一步之前,我们需要一个软盘印象,于是通过bximgae生成一个名为a.img的软盘映像
使用软盘绝对扇区读写工具将这个文件写到一张空白软盘的第一个扇区
Bochs的使用方法
上述步骤都成功后可开始调试过程,输入bochs -f bochsrc
然后,需要再输入c
程序及结果分析
最简单的引导扇区(Boot Sector)。虽然它不具有任何功能,但是它却能够直接在裸机上运行,不依赖其他软件。一个引导扇区是512个字节,并且以0xAA55为结束标识的扇区。
org指代码“开始位置的地址”,这里指的是从org开始的位置7c00h,$−就是说这段代码到目前的长度,times后面加数字表示进行填充,db表示byte,也就是说代码结束后就开始用0进行填充,直到一共有510个字节,dw表示word,最后填充0xaa55,加起来一共512B。
0xaa55是一个固定的格式,计算机加点自检查后会扫描512字节的文件末尾,如果有0xaa55就认定为引导文件,开始加载。org 07c00h表示实模式下的用户可以用来写的地址,此时加载到7c00h处,此时cs=7c00h,由于其他寄存器ds,es都没有被初始化,所以必须需要通过ax对其进行赋值,作为段寄存器cs并不能直接和ds,es进行赋值操作,因此需要借助ax这个寄存器。
call指令先将当前位置的地址push stack中,然后跳转到DispStr的位置开始执行,接下来就是将以对参数传递到寄存器中,bp中放ES:BP,cx中放长度,ax和bx放颜色的属性,然后调用10h中断,显示器收到信号,根据寄存器中的参数输出信号,最后ret弹出stack中的值,跳转到jmp中停止。