自制一个简单的启动扇区,打印hello,world!

自制一个简单的启动扇区,可以打印hello,world!

0,0
0,0

准备工作

计算机启动过程:按指令执行顺序划分为3个过程

  1. BIOS启动,第一条指令地址位于bios的映射(把bios的所有指令映射进内存)地址,所以bios启动,执行硬件检测和初始化,激活鼠标键盘,最后jmp到0x07c00处,这是code约定。
  2. 启动扇区启动,硬盘把启动扇区的指令映射到0x07c00处,指令从该扇区执行,最后jmp到IPL,也就是初始化程序加载器的内存地址
  3. 程序加载器启动, IPL作为加载器加载非常多的其他软件实现OS的启动。

启动扇区:
启动扇区位于硬盘的0面0道1扇区,只有512个字节,判断一个扇区是否为启动扇区,cpu只是简单的做了两次判断:

  1. 启动扇区的第一个字节不为0字节。
  2. 最后两个字节为0x55,0xaa。

这两个条件满足,就认为是启动扇区。

所以做一个简单的启动扇区只需要按下面这样做:
就3条汇编指令,“;”后面的都是注释。

;最简单的启动扇区
;启动扇区的判断条件:第一个字节不为0x00字节,最后两个字节为0x55,0xaa
;cpu执行全为0x00字节时会跳过,然后就会停住
;一个扇区为512个字节

db 0x01;保证第一个字节不为0x00字节

times 510-($-$$) db 0 ;剩余的509个字节用0字节填充。
;times n表示执行n次指令,$表示当前指令的内存偏移地址,$$表示扇区的开始地址,$-$$表示从扇区到当前指令的字节数

db 0x55,0xaa ;启动扇区flag标志

然后测试结果。

最简单的启动扇区测试

我使用VM Box虚拟机进行测试,新建一个虚拟机,启动设备设置为软盘,
用nasm工具把写好的汇编代码easyBootSector.asm汇编成二进制文件easyBootSector.img
.img文件是软盘文件,类似于镜像文件.iso,用哪种都类似,主要是要简单。
在这里插入图片描述
用winhex察看一下二进制机器码:
自制一个简单的启动扇区,打印hello,world!_第1张图片
机器码里就只有3个字节不是0字节,ok,配置好镜像文件,启动。

自制一个简单的启动扇区,打印hello,world!_第2张图片结果如下
只显示了一个下划线就halt待机了,什么显示也没有,因为没有做任何操作啊。
没有报操作系统未找到的错证明已经成功了。下面我们让它变得更漂亮。
自制一个简单的启动扇区,打印hello,world!_第3张图片

升级版启动扇区----打印 hello,world!

-_-

准备工作

BIOS作为ROM存储器里面保存了很多INT 中断函数,可以完成硬件的检测与初始化工作。自然,向显卡中输入数据控制显示器的输出也是可以的。

int 0x10中断函数就可以输出一个字符串,但是你要先给他传参数,他会自动从AX,BX等寄存器中取参数

所以类似于下面可以输出一个字节的字符:
参考资料见:int 10h中断例程

mov AH,0x0e ;AX累加寄存器的高8位,选择功能,0x0e为打印字符
mov AL,0x68 ;AX的低8位,字符码,0x68=h,其实就是ascii码也是机器码
mov BH,0 ;可以不设置
mov BL,00001011b ;8位颜色码,图形模式下可以设置颜色
int 0x10 ;调用函数,根据AH选择特定的功能,可以是打印也可以是设置光标位置

使用int 0x10中断函数打印一个字符:

自制一个简单的启动扇区,打印hello,world!_第4张图片
然后利用循环实现打印字符串!

-,-

升级版启动扇区代码如下:

;bootSector
;利用bios的int 0x10中断函数操作显卡显示字符串

ORG 0x7c00;指明程序在内存中的装载位置,这样才能使用SI

jmp entry;跳转到指令执行位置

msg:
	db "hello,world!"	;要显示的字符串,10
	db 0x0D,0x0A;回车换行一次,int 0x10可以解释控制指令

;输出字符串int 0x10(AH,AL,BH,BL);
entry: 
	mov SI,msg
	
;循环输出hello,world,一个字节一个字节的输出
	mov cx,14;循环次数
s:	
	mov AH,0x0e
	mov AL,[SI];字符码
	mov Bh,0
	mov BL,00001101b;颜色码,没用
	int 0x10;输出一个字符
	
	inc SI
	loop s

HLT ;halt,待机

times 510-($-$$) db 0;剩余的字节用0字节填充。
;times n表示执行n次指令,$表示当前指令的内存偏移地址,$$表示扇区的开始地址,$-$$表示从扇区到当前指令的字节数

db 0x55,0xaa

结果如下:
自制一个简单的启动扇区,打印hello,world!_第5张图片
美化版:
自制一个简单的启动扇区,打印hello,world!_第6张图片

参考书籍:30天自制操作系统

现在这个启动扇区只能被识别,没有其它功能,要想真正的实现功能还得实现IPL加载器,也就是jmp一下了。

你可能感兴趣的:(操作系统,汇编)