环境
- Time 2022-11-06
- WSL-Ubuntu 22.04
- NASM 2.15.05
前言
说明
参考:《x86汇编语言:从实模式到保护模式》李忠
参考:https://wiki.osdev.org/Boot_Sequence
如果计算机使用的 BIOS 启动,那么在开机自检后,会去查找启动盘。
如果做一个启动盘,就可以让 CPU 执行汇编指令了。
目标
生成一个可以被引导的文件。
主引导记录
来源:https://wiki.osdev.org/Boot_Sequence
Master Boot Record
The (legacy) BIOS checks bootable devices for a boot signature, a so called magic number. The boot signature is in a boot sector (sector number 0) and it contains the byte sequence 0x55, 0xAA at byte offsets 510 and 511 respectively. When the BIOS finds such a boot sector, it is loaded into memory at 0x0000:0x7c00 (segment 0, address 0x7c00). (However, some BIOS' load to 0x7c0:0x0000 (segment 0x07c0, offset 0), which resolves to the same physical address, but can be surprising. A good practice is to enforce CS:IP at the very start of your boot sector.)
主引导记录
BIOS 检查可引导设备的引导签名,即所谓的魔法数字。
引导签名位于引导扇区(扇区号 0)中,它包含字节序列0x55、0xAA,分别位于字节偏移 510 和 511。
当 BIOS 找到这样的引导扇区时,它会被加载到内存中的0x0000:0x7c00(段 0,地址 0x7c00)。
(但是,某些 BIOS 加载到 0x7c0:0x0000(段 0x07c0,偏移量 0),解析到相同的物理地址,但可能令人惊讶。
一个好的做法是在引导扇区的最开始强制设置 CS:IP。)
从这里看出,主引导记录可以启动,至少需要 512 字节,在 510 处是 0x55,在 511 处是 0xAA。
并且会被 BIOS 加载到物理地址为 0x7c00 的地方。(段和偏移之后学)
汇编程序
mov al,4
times 508 db 0
db 0x55
db 0xaa
times 伪指令是重复指令多少次,上面的意思是重复 508 次 db 指令。
db 伪指令使用后面的数据填充一个字节。
上次看过了 move al,4
为两个字节,加上 508 个字节,再加最后的两个字节,共 512 字节。
并且也满足了在 510 处是 0x55,在 511 处是 0xAA(偏移量从 0 开始)。
编译和查看
root@jiangbo12490:~/git/game# nasm main.asm
root@jiangbo12490:~/git/game# ll
-rw-r--r-- 1 root root 512 Nov 6 21:15 main
-rw-r--r-- 1 root root 39 Nov 6 20:18 main.asm
可以看到 main 二进制文件,确实是 512 字节。文件的二进制码如下:
root@jiangbo12490:~/git/game# xxd main
00000000: b004 0000 0000 0000 0000 0000 0000 0000 ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000110: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000120: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000130: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000140: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000170: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000190: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U.
总结
通过汇编程序,生成了一个可以启动的二进制文件。