4.使用机器码编写bios引导的程序
使用二进制编辑器手动编写 bootloader
直接用二进制编辑器写机器码来实现 bootloader 是完全可行的(早期操作系统开发常用此方法)。核心是 手动写出每条指令对应的机器码,并保证启动扇区规范:512 字节 + 结尾 0xAA55。
一、核心原理:指令 → 机器码对应关系
x86 16 位实模式指令有固定机器码格式,例如:
| 指令 | 机器码 | 说明 |
|---|---|---|
mov ah, 0x0e |
b4 0e |
BIOS 打印功能 |
mov al, 'H' |
b0 48 |
‘H’ 的 ASCII 码 0x48 |
int 0x10 |
cd 10 |
BIOS 视频中断 |
jmp loop(无限循环) |
eb fe |
相对偏移 0xfe 跳转自身 |
二、用二进制编辑器编写步骤(以打印 "Hi" 为例)
1. 确定指令与机器码
打印 'H' → 打印 'i' → 无限循环,对应机器码序列:
1 | b4 0e ; mov ah, 0x0e |
共 12 字节。
2. 填充剩余字节至 510 字节
启动扇区总长度 512 字节,前 510 字节为代码 + 填充。
填充字节数 = 510 - 12 = 498 字节,使用 0x00 填充。
3. 添加启动标志(最后 2 字节)
启动扇区必须以 0xAA55 结尾(小端存储,实际写入顺序为 0x55 0xAA)。
4. 使用二进制编辑器输入字节
示例(Linux 下):
1 | hexedit boot.bin |
操作步骤:
- 打开文件(不存在会创建)
- 输入十六进制模式下的字节:
- 前 12 字节:
b4 0e b0 48 cd 10 b0 69 cd 10 eb fe - 填充 498 个
00 - 末尾 2 字节:
55 aa
- 前 12 字节:
- 保存并退出(
F2保存,Ctrl+Q退出)
其他二进制编辑器如 bless、vim 的二进制模式也可使用。
三、验证文件正确性
使用 hexdump 检查:
1 | hexdump -C boot.bin |
应满足:
- 总长度 512 字节(显示
00000200结束) - 前 12 字节为指令机器码
- 中间 498 字节为
00 - 最后 2 字节为
55 aa
四、制作镜像并测试
可直接使用 boot.bin 或生成软盘镜像:
1 | dd if=boot.bin of=boot.img conv=notrunc |
挂载到 VMware 或其他虚拟机并启动,屏幕应显示:
1 | Hi |
说明手动编写的机器码已生效。
五、关键注意事项
- 机器码准确性
- 每条 x86 指令的机器码必须严格对应
- 可参考 x86 指令集手册或在线机器码查询工具
- 指令长度
- 16 位指令长度可变(1~6 字节)
- 确保每条指令长度正确,否则后续指令可能被覆盖
- 填充计算
- 启动扇区总长度必须 512 字节,否则 BIOS 无法识别
这种方式完全绕开汇编器,直接操作机器码,虽然繁琐,但能直观理解指令与二进制的对应关系,是深入学习底层原理的好方法。
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
