从0创建一个OS (九) 32-bit模式的打印字符串函数
学习如何在32-bit模式下不借助BIOS的0x10号中断打印字符串
关键字:32-bit保护模式; VGA; 视频存储区域
目标: 学会在32-bit保护模式下打印字符串
理论基础
32-bit保护模式
32-bit保护模式设计的内容非常多,十篇博客也写不完,因此这里只对32-bit保护模式的要点做简单介绍:
1. 32-bit保护模式下可以使用32bit的寄存器和寻址模式
2. 32-bit保护模式下可以使用受保护的存储区域,虚拟内存
其中寻址模式,受保护的存储区域,虚拟内存都依赖于GDT(Global Descriptor Table),即全局描述符表,这是保护模式中非常重要的一个概念和数据结构. 我们在后续的博客中会对GDT做相关介绍,本节的目的只是学习32-bit模式下的字符串打印.
想要详细了解保护模式的读者可以阅读《x86_x64体系探索及编程》(邓志),里面有非常详细的操作系统模式介绍.
VGA显示
显示大小: 25(行) × 80(列)
数据范围:0xB8000 ~ 0xB8000+25×80×2
显示格式:在数据范围内,每2个字节对应显示一个字符,其中偶数地址的字节代表字符(ASCII码值),奇数地址的字节代表字符属性,具体属性有字符颜色(低4bit),字符背景颜色(高4bit),具体颜色如下,参考自Assembly Language Color of Text
hex | bin | color |
---|---|---|
0 | 0000 | black |
1 | 0001 | blue |
2 | 0010 | green |
3 | 0011 | cyan |
4 | 0100 | red |
5 | 0101 | magenta |
6 | 0110 | brown |
7 | 0111 | light gray |
8 | 1000 | dark gray |
9 | 1001 | light blue |
a | 1010 | light green |
b | 1011 | light cyan |
c | 1100 | light red |
d | 1101 | light magenta |
e | 1110 | yellow |
f | 1111 | white |
源码
本节的源码无法测试,因为我们目前还没有学习创建32-bit保护模式中的GDT,所以这里只给出源码,说明如何在32-bit保护模式下进行打印字符串任务.
; ============================================================== ; ||| print_string_pm函数说明 ||| ; -------------------------------------------------------------- ; input: ebx-需要打印的字符串的首地址 ; return: 不返回值 ; 功能: 打印字符串 ; ============================================================== [bits 32] ; 使用32bit 保护模式 ; 定义有意义的常量 VIDEO_MEMORY equ 0xB8000 WHITE_ON_BLACK equ 0x0F ; 每个字符的颜色,此为白底黑字 print_string_pm: pusha mov edx, VIDEO_MEMORY print_string_pm_loop: mov al, [ebx] ; [ebx]是我们的字符的地址 mov ah, WHITE_ON_BLACK cmp al, 0 ; 查看是否是字符串末尾 je print_string_pm_done mov [edx], ax ; 将字符+颜色属性写入到视频存储区域 add ebx, 1 ; 下一个字符 add edx, 2 ; 下一个存储位置 jmp print_string_pm_loop print_string_pm_done: popa ret