0
点赞
收藏
分享

微信扫一扫

30天OS学习,显示中文

zhongjh 2022-04-22 阅读 68

学习日本作者川和秀实的作品,《30天自制操作系统》,感兴趣的地方有两个。一个是,这个系统能够显示图形界面。另一个是,这个系统能够显示文字。

原书所显示的文字是日本的平假名,片假名,日本汉字。对于中文汉字,原书是没有讲的,而中国的人民邮电出版社的翻译者,在翻译的时候,插入了关于显示中文的说明。

我在看这一部分的章节的时候,我其实已经是有些看不下去了。因为,在前面的一些个章节,我觉得,程序写的有些晦涩,讲得也不是很详细。

原书整体的写作风格,给我的感觉是,开始的部分挺容易懂的。到了后面,突然间就有了一些个难度很高的代码。这种突然提高难度,算是原书的一个问题了。我觉得,这应该是作者本人故意这么设置的。也就是,我觉得,作者写作这本书,其目的,并不是为了让学习者学会写内核,而是为了劝退学习操作系统的人。

其实在学习编程知识的时候,这种现象,经常是能够见到的。我在学习编程的时候,王爽老师的《汇编语言》教材算是一本好的教材。其余的教材,大多数,都会给你设置坑点。不喜欢这样的设置坑点的做法,但是呢,为了学习,还必须要尽量地去学习克服这些个坑点。

像是作者川和秀实的代码,我若是认真一些,仔细一些地去分析的话,也是可以理解的。可是,第一次看这本书,心态上,还是显得着急了一些。一些个调用层次多一些的代码,就缺乏耐心去细致地分析了。

虽然说,作者的很多内容,我没有细研究,也没有理解,但是呢,在显示中文方面,我倒是做出来了。

显示中文,其实也不是很容易。在写这个程序的时候,我也是经历了好多的难点。

显示中文,比较基本的,那就是得有中文字库。

在书中,翻译者给出了中文的字库文件名称,HZK16。

这个HZK16字库文件,网上很容易下载到,CSDN里面也有很多的下载链接。,

在这里,我提供我这里的一个字库文件链接。

https://download.csdn.net/download/sheling2017/85198255

我提供的这个字库文件链接,里面包含着多种尺寸与字体的字库。其中呢,HZK16,位于16*16的文件夹里面。在我提供的这个资源里面,HZK16字库文件的名称,并不是纯粹地叫做HZK16,而是会在【HZK16】字样的后面带上一些个后缀。不同的后缀,表示不同的字体。比如,【HZK16S】文件为HZK16的宋体字版本的字库,【HZK16F】为仿宋体的HZK16字库,【HK16H】为 黑体字版本的HZK16字库。

所谓HZK16的16,指的是,这个字库文件的尺寸,为16*16像素单位的文字。

准备好了字库之后,接下来呢,还需要编程,将其显示出来。

中文汉字的显示的思路,与作者川和秀实本人在原书中给出的显示日文汉字的思路有所不同。

16*16,是指,显示一个文字,它需要绘制一个像素方形点阵。这个方形的点阵,每一行有16个像素点,一共有16行。

这个16*16的方形点阵,作者川和秀实在显示日文汉字的时候,它是将其分为左右两半,每一半都是8*16的点阵。也就是,每一行为8个像素点,一共有16行。这样的8*16,横向地排布两个,就可以形成16*16的点阵了。

显示完了左半部分的点阵以后,再来显示着右半部分的8*16的点阵。方法也是用char类型的变量,每次显示一行的8个像素点。显示了第一行以后,再去显示着第2行,第3行,直到显示完第16行。然后呢,右半部分的8*16的点阵就显示完了。

左半部分与右半部分都显示完了以后,整个的16*16的点阵,也就显示完了。

在川和秀实先生的程序里面,日文汉字就是这样子来显示着的。

读者需要注意,在这里,我是将char 和unsigned char,都笼统地称为char类型。

我自己去编写程序的时候,中文字体的显示,不是这个思路。中文字体的显示思路如下。

显示中文字体,也是用char类型的变量。

char类型变量,每一次可以处理8个像素点。在实际去显示的时候,先是去显示着第一行的左边的8个像素点,然后呢,是去显示着第一行的右边的8个像素点。经过这两次的显示工作,第一行就算是显示完了。

显示完第一行以后,接着去显示第二行。显示第二行的时候,也是说,用char类型变量,先去显示着左边的8个像素点,然后再去显示着右边的8个像素点。显示完了第二行,再去用这样的方法,显示着第三行,第四行,直到显示完最后的第16行。

显示完了16行以后,一个汉字就显示完了。

在下面,我将我的程序的一部分贴出来。

void putfont_chinese(char *vram, int xsize, int x, int y, char c, unsigned char *font)
{
	int i, j;
	char *p; /* data */;
	short d;
	i = j = 0;
	while (i < 16) 
	{
		p = vram + (y + i) * xsize + x;
		d = font[j++];
		if ((d & 0x80) != 0) { p[0] = c; }
		if ((d & 0x40) != 0) { p[1] = c; }
		if ((d & 0x20) != 0) { p[2] = c; }
		if ((d & 0x10) != 0) { p[3] = c; }
		if ((d & 0x08) != 0) { p[4] = c; }
		if ((d & 0x04) != 0) { p[5] = c; }
		if ((d & 0x02) != 0) { p[6] = c; }
		if ((d & 0x01) != 0) { p[7] = c; }
		
		d = font[j++];
		if ((d & 0x80) != 0) { p[8] = c; }
		if ((d & 0x40) != 0) { p[9] = c; }
		if ((d & 0x20) != 0) { p[10] = c; }
		if ((d & 0x10) != 0) { p[11] = c; }
		if ((d & 0x08) != 0) { p[12] = c; }
		if ((d & 0x04) != 0) { p[13] = c; }
		if ((d & 0x02) != 0) { p[14] = c; }
		if ((d & 0x01) != 0) { p[15] = c; }
		i++;
	}
	return;
}

在这里,我给出的并不是完整的程序项目。可能有的代码行,理解起来会有点困难。比如说,下面的这一行。

p = vram + (y + i) * xsize + x;

上面的这一行,大家可以暂时将其忽略掉,而直接去看其它的代码行。然后呢,程序还涉及了位运算的知识。对于位运算,如果大家不熟悉的话,请自行复习C语言的位运算的知识。

在忽略对变量p赋值这一行,以及具备了一些个位运算的基础知识以后,大家去看上面的代码行,应该是能够理解的。

若是大家理解了上面的代码,那么,我这里的显示中文的思路,处理16*16像素点阵的思路,大家也就算是理解了。

解决了16*16点阵的问题以后,接下来呢,还有汉字的编码的问题。

中文字体的显示,有一种编码,叫做GB2312。

这个GB2312,它是一种字符集,全称叫做【信息交换用汉字编码字符集】,是由中国国家标准总局1980年发布,1981年5月1日开始实施的一套国家标准,标准号是GB 2312—1980。

现在呢,除了Gb2312之外,还有Gb18030,GBK码几个版本。其中呢,Gb18030,GBK,都是兼容GB2312的。

我在想要显示中文的时候,我所查询的,就是汉字的GBK内码。我是一个一个地去查询的。

查询的表格如下。

/*
子D7D3
曰D4BB
:A3BA
学D1A7
而B6F8
时CAB1
习CFB0
之D6AE
,A3AC
不B2BB
亦D2E0
说CBB5
乎BAF5
?A3BF
有D3D0
朋C5F3
自D7D4
远D4B6
方B7BD
来C0B4
,A3AC
不B2BB
亦D2E0
乐C0D6
乎BAF5
?A3BF
人C8CB
不B2BB
知D6AA
而B6F8
不B2BB
愠E3B3
,A3AC
不B2BB
亦D2E0
君BEFD
子D7D3
乎BAF5
?A3BF
*/	

大家应该很熟悉上面的一句话吧。

在下面,我将我的程序的两个版本的链接贴出来。大家可以将这两个版本的代码包给下载回去。然后呢,大家需要自行安装安装bochs虚拟机,然后按照我的代码包里面的说明,来运行着代码包里面的程序。

https://download.csdn.net/download/sheling2017/85198122

https://download.csdn.net/download/sheling2017/85198131

大体上,对于这个显示中文的程序,我在完成了程序以后,我是觉得停开心的。

下面是运行结果的截图。

如上图所示,我除了显示中文之外,还显示了一段英文。

能够在自己的小内核里面显示着中文,我还是挺开心的。 

在开心之外,也觉得,自己的编程能力,还是有待于提升的。因为,在程序运行出现问题,在需要我去调试的时候,我还是显得很吃力的。

程序调试的方法,反汇编,英文手册,好多的东西,我都是需要去学习的。而这些个东西,在完成中文显示程序的当时,我还是远远没有完成学习的。

说起来的话,其实,内核的学习,本就是一个长期与复杂的学习过程。

为啥林纳斯托瓦茨那一代人在编写内核的时候,显得那么地从容。而如今,我们这一代人想要去学习内核的时候,却显得很吃力呢?

多说无益,大概,想要学好内核知识的话,还得是不断地努力着的。

有空的话,我会去花时间来系统地写博客,讲解内核知识。

当然了,我自己目前的学习水平也是有限。

因此,我是决定,将博客的专栏名字,称为学习笔记。

有空的话,欢迎大家关注我的学习笔记。

举报

相关推荐

0 条评论