通过学习《x86汇编语言-从实模式到保护模式》一书,我终于明白了操作系统是如何安装的,以及自己写了一个小小的,算不上安装程序的helloworld啦。
操作系统是如何安装的
这里只说如何从磁盘安装(其他的我也不知道啊)。是这样:intel CPU会先读取磁盘的第一个扇区,这个扇区被称为主引导扇区。ROM-BIOS会将其加载到0x0000:0x7C00
的地方,然后判断是否有效(判断的方式是看扇区最后的两个字节是不是0x55和0xaa)。如果有效,那么就会跳到0x000:0x7C00
去执行代码啦。
也就是说,我们只要将安装程序放在磁盘的第一扇区,并且在最后加上0x55,0xaa就可以让BIOS在启动的时候执行我们安装程序的代码啦。这也就是操作系统通过磁盘安装的底层过程。
HelloWorld
我自己按照书上编写了一个可以在屏幕上输出的HelloWorld程序:
mov ax, 0xB800
mov es, ax
mov byte [es:0x00], 'H'
mov byte [es:0x01], 0x07
mov byte [es:0x02], 'e'
mov byte [es:0x03], 0x07
mov byte [es:0x04], 'l'
mov byte [es:0x05], 0x07
mov byte [es:0x06], 'l'
mov byte [es:0x07], 0x07
mov byte [es:0x08], 'o'
mov byte [es:0x09], 0x07
mov byte [es:0x0A], ' '
mov byte [es:0x0B], 0x07
mov byte [es:0x0C], 'W'
mov byte [es:0x0D], 0x07
mov byte [es:0x0E], 'o'
mov byte [es:0x0F], 0x07
mov byte [es:0x10], 'r'
mov byte [es:0x11], 0x07
mov byte [es:0x12], 'l'
mov byte [es:0x13], 0x07
mov byte [es:0x14], 'd'
mov byte [es:0x15], 0x07
infi jmp near infi
current equ 510-$
times current db 0
db 0x55, 0xaa
由于0xB800
处是显存,所以我们只要将字符写入显存就可以在屏幕上显示字符了。这里我写入了hello world
。然后使用一个无限循环来循环我们的程序,防止CPU无尽地向下执行。最后使用0填充了到磁盘末尾的所有空闲空间,然后db 0x55, 0xaa
来放入055,0xaa。
程序是使用nasm编写的,编译的话只要:
|
|
即可。
然后就是按照书上的方法,将bin文件刷到虚拟机的虚拟硬盘里面了。我自己写了一个刷固定VHD文件的小工具来方便我在Mac和Linux下刷(Windows也可以用)。刷进去之后放在虚拟机里面就可以转出来啦: