老李手把手之操作系统(3)
老李手把手之操作系统(3)
本章的目的是:在可引导扇区的代码中增加一些文字输出
通过老李手把手之操作系统(2),我们已经能够将我们的引导扇区代码正常执行,只不过它是一个死循环,我们是否可以修改下代码,让屏幕上打印出 Hello 呢?
这听上去不是一件很酷的事情,因为我们在学习任何语言的时候,第一件事情就是写个 hello world 的程序,这并不是非常了不起,但是请大家思考下,
在没有操作系统的支持下,大家知道如何在屏幕打印 hello world 么~?我想 99% 的人应该不会,因此我认为能不依赖任何系统软件,而直接能在屏幕上打印文字,
这非常的 cool。给大家 10 分钟的时候思考下,如果是你,你觉得如何能做到?
需要自行学习的概念:
interrupts
CPU registers
ASCII 编码
在启动界面中输出文字原理
BIOS 会通过软件中断提供向屏幕显示的服务,因此,使用 BIOS 的这一功能就可以完成我们今天的任务。具体的方法如下:
设置 ah 寄存器为 0x0e,并调用 INT 0x10 中断,屏幕上就会打印 al 中的内容(al 中存放的是字符的 ASCII 码)
因此代码应该如下:
mov ah, 0x0e
mov al, 'H'
int 0x10
我们并没有直接和显卡、显示器打交道,而是通过 BIOS 来进行的交互,这本身也不算什么特别大的本领。
BIOS 确实具有不小的作用,这点我们必须承认。比如 DOS 系统就依赖 BIOS,
但是对于现代的操作系统,往往只在引导系统时使用 BIOS,操作系统运行后就不再使用。
完整代码(引导扇区)
mov ah, 0x0e ; tty mode
mov al, 'H'
int 0x10
mov al, 'e'
int 0x10
mov al, 'l'
int 0x10
int 0x10 ; 'l' is still on al, remember?
mov al, 'o'
int 0x10
jmp $ ; jump to current address = infinite loop
; padding and magic number
times 510 - ($-$$) db 0
dw 0xaa55
编译如下:
nasm -fbin boot_sect_hello.asm -o boot_sect_hello.bin
我们可以通过 xxd file.bin
来查看文件的二进制内容
root@ubuntu:/# xxd boot_sect_hello.bin
00000000: b40e b048 cd10 b065 cd10 b06c cd10 cd10 ...H...e...l....
00000010: b06f cd10 ebfe 0000 0000 0000 0000 0000 .o..............
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.
执行的方法:
qemu-system-x86_64 boot_sect_hello.bin
最终效果如下: