VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 网络工程 > Linux 教程 >
  • 【操作系统真象还原】04 编写MBR分区(二)和显卡对话

前言

通过BIOS提供的中断,我们的MBR程序在屏幕上输出了绿油油的 Hi from MBR!。但只有在 实模式 下,我们才可以使用BIOS中断,而我们要编写的操作系统是运行在32位 保护模式 下的程序。既然不能调用BIOS中断了,那么我们就直接和显卡对话吧。

外部硬件与CPU

忙碌的CPU要和大量的硬件打交道,处理大量由硬件传递的数据。不同的硬件传递的数据是不一样的、响应速度是不一样的,而CPU的时间又是那么的宝贵,不能被浪费,所以硬件工程师们指定了一系列的IO接口,作为CPU与硬件之间的中间人。首先,IO接口用有缓冲区,在一定程度上缓解了CPU与硬件设备响应速度不匹配;其次,IO接口还拥有处理数据格式的功能,减少CPU的工作量。
还有些需要CPU频繁向其传输数据的硬件(如:显卡),直接将自身的内存空间,映射到计算机内存的某块空间上,只要在特定的地址上填写数据,就相当于在该硬件的内存上填写了数据。

和显卡对话

显存分布

现在,我们知道显卡将自己部分的内存空间映射到可计算机的内存中。想要和显卡对话,我们就要知道这块映射空间在哪块内存中(其实显卡也有自己的IO接口,不过我们不涉及)。
显存

因为我们想要在屏幕上显示文字,所以我们选择将数据发送到起始地址为 b8000 的适用于 文本模式 的显存。

数据格式

在 文本模式 下,表示一个字符需要两个字节。第一个字节表示 字符ASCII码,第二个字节表示 字符属性 。
数据格式

因为可表示颜色有限,所以有一份整理好的字符属性表可供大家参考。
字符属性

改进MBR

知道了怎么和显卡对话,我们现在就可以来改进之前编写的 MBR 了。

初始化段寄存器 gs

因为实模式下CPU的寻址方式为 段基地址:偏移地址,即 物理地址 = 段基地址 * 16 + 偏移地址。而文字模式显存起始地址为 b8000,所以我们将 gs 寄存器的值初始化为 0xb800,即:

mov ax, 0xb800
mov gs, ax

编写 putchar 函数

将 di 寄存器初始化为 0,通过 gs:di 寻址。所以 putchar 函数:

; al: ASCII码
; bl: 字符属性
putchar:
    mov [gs:di], al  ; 放置ASCII码
    inc di           ; di++
    mov [gs:di], bl  ; 放置字符属性
    inc di
    ret              ; return

编写 print_message 函数

我们将要打印的字符串 Hi from MBR!,通过 message db "Hi from MBR!" db 0 的方式储存。其中 message 就相当于一个 char *0 代表字符串的结束符。
所以我们可以通过 si 寄存器保存 message,即 字符串的起始地址,通过 inc si 移动指针,通过 [si] 对指针解引用得到字符,通过 putchar 函数输出字符,通过判断字符是否为 0 从而判断是否到达字符串末尾。所以 print_message 函数:

print_message:
  .init:
    mov ax, message
    mov si, ax      ; 让 ds:si 指向 message 的开头
    mov bl, 0x07    ; 字符属性:黑底白字
  .print:
    mov al, [si]    ; 读取字符串
    or  al, 0       ; al | 0
    jz  .end        ; 若为0,则输出完毕
    call putchar    ; 不为0,则输出 al
    inc si          ; si++
    jmp .print      ; 循环
  .end:
    jmp $

MBR总览

点击查看代码
## bochs 模拟 最后编译并写入镜像,运行bochs:

结果

可以看见,我们成功输出了字符串 Hi from MBR!,但光标的位置并不对劲。下一篇博客,我们来做一个属于自己的光标,并编写一个函数来监听键盘输入,并将键盘的输入打印到屏幕上!敬请期待(手动狗头)。

 

出处:https://www.cnblogs.com/zyjjjzp/p/15334135.html


相关教程