博主:zhangkai
未经允许不得转载!!!
1.试用结构体改写
个人理解的是作者希望更好的组织图像信息的获取。
在harib02b中我们可以看到:
作者定义了一个类型为BOOTINFO的结构体变量,也就是储存启动画面信息的结构体。
struct BOOTINFO {
char cyls, leds, vmode, reserve;
short scrnx, scrny;
char *vram;
};
查看我们的汇编代码 asmhead.nas
会发现我们在某一区域完全存放了这些信息,那么只要指示我们结构体变量的地址到这里就OK
这里的地址是0x0ff0于是就有这样一句代码:
binfo = (struct BOOTINFO *) 0x0ff0;
我们定义了一个结构体变量指针以后 将0x0ff0地址给它,那么现在binfo里就是结构体地址,通过*binfo就可以访问到这个结构体。
xsize = (*binfo).scrnx;
ysize = (*binfo).scrny;
vram = (*binfo).vram;
作者再依次获取这些变量。
那么相比以前发生了什么改变呢?我们查看第四天harib01h的bootpack.c
在第四天里,这些信息的获取完全是在我们已知的情况下赋值,却没有利用到我们在汇编里已经组织好的信息。
可以看出来作者在一步步优化信息结构。
2.结构体使用的进一步优化
第二点是对第一点结构体使用的进一步优化。在harib02c的bootpack.c可以看到:
省去了对一些变量的声明,直接用->访问获取后传递参数。
3.显示字符
因为32位模式下无法调用BIOS ,现在将字符输出到屏幕的方法就是将字符当作像素点阵,通过指定位置颜色显示而组成一个字符。
字符A由8×16个像素组成,每8个像素为一个字节,也就是一个字符有16个字节。
我们的屏幕是320×200像素。
为什么要转化成01二进制数呢,我们可以对每一行的每一位数进行检测,如果是1那么我们就涂上颜色,如果不是我们就不操作。
我们在harib02d中查看bootpack.c
作者用16进制将字符A储存了起来。
我们看一下绘图函数:
循环数组里16个数据,并且对每个数据的8位进行依次判断。如果是1那么就涂上颜色char c
例如我们看第一个if判断:
if ((d & 0x80) != 0) { p[0] = c; }
0x80其实就是二进制数10000000
进行与运算就是判断每一个数据的第一位是不是1,如果是1那么就满足条件涂上颜色。
尝试运行一下:
4.增加字体
第三点提到的显示字符的方法使用不方便,作者为我们提供了一种新的方法。
打开harib02e中的hankaku.txt 是一个字符数据包
作者用自制的编译器将256个字符的文本文件转化为二进制文件后进一步制作位obj目标文件。然后和bootpak.obj连接起来。
作者告诉我们这样的效果相当于将以下两句进行汇编。
_hankanku:
DB 各种数据(共4096字节)
为了在C语言中使用这些数据,在C语言前加上:
extern char hankaku[4096]
作者提供的字符数据按照ASCII 字符编码,含有256个字符,A的字符编码是0x41 放在 hankaku+0x41*16 开始的16个字节里 而C语言中A的字符编码也是0x41 那么也可以写成 hankaku+A*16
使用以上数据,更改C语言代码:
尝试写入ABC123
make run一下:
正常运行。
5.显示字符串
作者写了一个用于显示的字符串的函数,我们打开harib02f中的bootpack.c
在主函数里显示几个字符串
我们make run 一下
6.显示变量值
作者使用了一个名为sprintf的函数,sprintf函数将要输出的内容作为字符串写在内存当中
函数的使用方法:
sprintf(地址,格式,值,值,值,...)
在主函数中使用sprintf函数:
先用sprintf函数将"scrnx = %d"字符串写到内存当中,然后用putfont8函数显示指定内存处的字符串。
我们make run一下:
7.显示鼠标指针
将鼠标指针显示到屏幕的方法也是在内存中写入数据
for循环处用于将鼠标的颜色数据写入mouse[ ]数组中。
鼠标是16×16块状区域,作者也写了一个专门用于显示块状区域数据的函数。
px0和py0是鼠标的x和y坐标,buf就是我们的mouse数据数组。
我们试着make run一下
8.GDT 和 IDT的初始化
这一步个人觉得留到和明天一起看更好
今天就这样啦 收工