30天自制操作系统
上QQ阅读APP看书,第一时间看更新

8 32位模式前期准备

今天还有些时间,再往下讲一点吧。

现在,汇编语言的开发告一段落,我们要开始以C语言为主进行开发了,这是我们当前的目标。

笔者准备的C编译器,只能生成32位模式的机器语言。如果一定要生成16位模式机器语言,虽然也不是做不到,但是很费事,还没什么好处,所以就用32位模式吧。

所谓32位模式,指的是CPU的模式。CPU有16位和32位两种模式。如果以16位模式启动的话,用AX和CX等16位寄存器会非常方便,但反过来,像EAX和ECX等32位的寄存器,使用起来就很麻烦。另外,16位模式和32位模式中,机器语言的命令代码不一样。同样的机器语言,解释的方法也不一样,所以16位模式的机器语言在32位模式下不能运行,反之亦然。

32位模式下可以使用的内存容量远远大于1MB。另外,CPU的自我保护功能(识别出可疑的机器语言并进行屏蔽,以免破坏系统)在16位下不能用,但32位下能用。既然有这么多优点,当然要使用32位模式了。

■■■■■

可是,如果用32位模式就不能调用BIOS功能了。这是因为BIOS是用16位机器语言写的。如果我们有什么事情想用BIOS来做,那就全部都放在开头先做,因为一旦进入32位模式就不能调用BIOS函数了。(当然,也有从32位返回到16位的方法,但是非常费工夫,所以本书不予赘述。)

再回头说说要使用BIOS做的事情。画面模式的设定已经做完了,接下来还想从BIOS得到键盘状态。所谓键盘状态,是指NumLock是ON还是OFF等这些状态。

所以,我们这次只修改了haribote.nas。修改后的程序就是projects/03_day下的harib00h。

本次的haribote.nas

; haribote-os
; TAB=4

; 有关BOOT_INFO
CYLS     EQU      0x0ff0           ; 设定启动区
LEDS     EQU      0x0ff1
VMODE   EQU      0x0ff2           ; 关于颜色数目的信息。颜色的位数。
SCRNX   EQU      0x0ff4           ; 分辨率的X(screen x)
SCRNY   EQU      0x0ff6           ; 分辨率的Y(screen y)
VRAM     EQU      0x0ff8           ; 图像缓冲区的开始地址

        ORG      0xc200           ; 这个程序将要被装载到内存的什么地方呢?
        MOV      AL,0x13          ; VGA显卡,320x200x8位彩色
        MOV      AH,0x00
        INT      0x10
        MOV      BYTE [VMODE],8  ; 记录画面模式
        MOV      WORD [SCRNX],320
        MOV      WORD [SCRNY],200
        MOV      DWORD [VRAM],0x000a0000

;用BIOS取得键盘上各种LED指示灯的状态
        MOV      AH,0x02
        INT      0x16              ; keyboard BIOS
        MOV      [LEDS], AL

fin:
        HLT
        JMP      fin

看一下程序就能明白,设置画面模式之后,还把画面模式的信息保存在了内存里。这是因为,以后我们可能要支持各种不同的画面模式,这就需要把现在的设置信息保存起来以备后用。我们暂且将启动时的信息称为BOOT_INFO。INFO是英文information(信息)的缩写。

■■■■■

[VRAM]里保存的是0xa0000。在电脑的世界里,VRAM指的是显卡内存(video RAM),也就是用来显示画面的内存。这一块内存当然可以像一般的内存一样存储数据,但VRAM的功能不仅限于此,它的各个地址都对应着画面上的像素,可以利用这一机制在画面上绘制出五彩缤纷的图案。

其实VRAM分布在内存分布图上好几个不同的地方。这是因为,不同画面模式的像素数也不一样。当画面模式为〇×时使用这个VRAM;而画面模式为◇△时可能使用那个VRAM,像这样,不同画面模式可以使用的内存也不一样。所以我们就预先把要使用的VRAM地址保存在BOOT_INFO里以备后用。

这次VRAM的值是0xa0000。这个值又是从哪儿得来的呢?还是来看看我们每次都参考的(AT)BIOS支持网页。在INT 0x10的说明的最后写着,这种画面模式下“VRAM是0xa0000~0xaffff的64KB”。

另外,我们还把画面的像素数、颜色数,以及从BIOS取得的键盘信息都保存了起来。保存位置是在内存0x0ff0附近。从内存分布图上看,这一块并没被使用,所以应该没问题。