写点什么

自制操作系统日记(7):字符串显示

作者:
  • 2022-11-16
    四川
  • 本文字数:2199 字

    阅读完需:约 7 分钟

代码仓库地址:https://github.com/freedom-xiao007/operating-system

简介

上篇中我们在屏幕上画出了界面的大致轮廓,系统有了点模样,本篇继续跟着书籍,让程序中的字符串显示在屏幕上

效果展示

先放最终的效果,可以看到显示了字符串,非常 nice,如下图:


字体制作

以前一直疑惑为啥在桌面中需要字体,打印字符串不都是基本的吗?


到这步才知道在桌面系统中,显示字符已经是图形化的了,是以填充像素的方式显示的字符串


搞自己的字体太麻烦了,我们直接抄《30 天自制操作系统》中字体,但根据我们当前的情况编译上有些不同的地方


首先把书中的源 txt 和两个工具复制到我们的工程中,即


  • hankaku.txt

  • makefont.exe

  • bin2obj.exe


这三个东西也上传仓库中了


接下来的制作字体基本步骤大致如下:


  • 1.将 txt 编程 bin

  • 2.将 bin 编程 obj

  • 3.将 obj 变成 nasm 汇编

  • 4.合并到 kernel.asm 中


一键运行脚本根据当前情况进行相关命令的新增和修改,完整如下,对命令添加了相关的注释:


D:\\software\\NASM\\nasm.exe bootsect.asm -o bootsect.bin -l bootsect.lstD:\\software\\NASM\\nasm.exe setup.asm -o setup.bin  -l setup.lst
@REM 主函数编译gcc -m32 -fno-asynchronous-unwind-tables -s -O2 -c -o .\\c\\start.o .\\c\\start.cD:\\software\\objconv\\objconv.exe -fnasm .\\c\\start.o .\\c\\nasm\\start.asm
@REM 字体文件编译.\makefont.exe .\hankaku.txt .\hankaku.bin.\bin2obj.exe .\hankaku.bin .\hankaku.obj _hankakuD:\\software\\objconv\\objconv.exe -fnasm .\hankaku.obj .\\c\\nasm\\hankaku.asm
@REM 处理生成的nasm不合理的的地方D:\\software\\python3\\python.exe E:\\code\\python\\self\\tools\\tools\\objconv2nasm_clearn.py
@REM 合并文件,编译运行copy /B head.asm+.\\c\\clean\\start.asm+func.asm+.\\c\\clean\\hankaku.asm kernel.asmD:\\software\\NASM\\nasm.exe kernel.asm -o kernel.bin -l kernel.lstcopy /B bootsect.bin+setup.bin+kernel.bin os.isoD:\\software\\Bochs-2.7\\bochs -q -f D:\\software\\Bochs-2.7\\dlxlinux\\bochsrc_m.bxrc
复制代码


python 脚本进行了相关的变化,以前是读取指定的文件进行处理,目前改为读取/c/nasm 下的所有文件,处理后放到/c/clean 目录下


对应的完整代码如下:


import os

def clean_nasm_file(file_name, nasm_path, clean_path): nasm_file = nasm_path + "\\" + file_name clean_file = clean_path + "\\" + file_name with open(clean_file, "w") as fw: with open(nasm_file, "r") as fr: content = fr.readline() while content: if content.startswith("global") or content.startswith("extern"): content = fr.readline() continue content = content.replace("noexecute", "") content = content.replace("execute", "") fw.write(content) content = fr.readline()

if __name__ == "__main__": nasm_path = "E:\\code\\other\\self\\operating-system\\c\\nasm" clean_path = "E:\\code\\other\\self\\operating-system\\c\\clean" files = os.listdir(nasm_path) for file in files: if not os.path.isdir(file): clean_nasm_file(file, nasm_path, clean_path)
复制代码


这样我们就处理完成了,虽然不想书中说的那样链接,但我们生成 nasm 汇编后,还是能正常工作的

字符串打印还是编写

需要编写两个函数,一个打印单个字符的,一个打印字符串的


打印字符串的循环调用打印单个字符的即可


新增的相关代码如下:


......void putfont8(char *vram, int xsize, int x, int y, char c, char *font);void putfont8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s);
void start(void){ ......
putfont8_asc(vram, xsize, 8, 8, COL8_FFFFFF, "Hollo OS!");
......}
void putfont8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s){ extern char hankaku[4096]; /* C语言中,字符串都是以0x00结尾 */ for (; *s != 0x00; s++) { putfont8(vram, xsize, x, y, c, hankaku + *s * 16); x += 8; } return; }
void putfont8(char *vram, int xsize, int x, int y, char c, char *font){ int i; char *p, d /* data */; for (i = 0; i < 16; i++) { p = vram + (y + i) * xsize + x; d = font[i]; 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; } } return;}
复制代码


还是比较简单的,照抄即可,接下来就是一键运行,就成功显示文章开头的画面,非常完成

总结

书中其实并没有单独讲字符串显示,而是将字符串显示,键盘处理和鼠标处理混合到一起了


感觉上后面两者还是比较麻烦的,所以这里单独讲字符串显示的抽处理,其他两个放到后面处理

发布于: 刚刚阅读数: 4
用户头像

关注

还未添加个人签名 2018-09-09 加入

代码是门手艺活,也是门艺术活

评论

发布
暂无评论
自制操作系统日记(7):字符串显示_操作系统_萧_InfoQ写作社区