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

news2025/1/15 13:15:13

代码仓库地址: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.lst
D:\\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.c
D:\\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 _hankaku
D:\\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.asm
D:\\software\\NASM\\nasm.exe kernel.asm -o kernel.bin -l kernel.lst
copy /B bootsect.bin+setup.bin+kernel.bin  os.iso
D:\\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;
}

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

总结

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/10535.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux磁盘分区,挂载介绍

分区的方式: mbr分区: 1.最多支持四个主分区 ⒉系统只能安装在主分区 3.扩展分区要占一个主分区 4.MBR最大只支持2TB&#xff0c;但拥有最好的兼容性 gtp分区: 1.支持无限多个主分区&#xff08;但操作系统可能限制&#xff0c;比如windows下最多128个分区) ⒉.最大支持18E…

仿大众点评——秒杀系统部分02

秒杀系统优化 接口限流和安全措施 令牌桶限流单用户访问频率限流抢购接口隐藏 接口限流&#xff1a; 在面临高并发的请购请求时&#xff0c;我们如果不对接口进行限流&#xff0c;可能会对后台系统造成极大的压力。尤其是对于下单的接口&#xff0c;过多的请求打到数据库会对…

MVCC 底层实现原理

文章目录概述事务并发出现的问题脏读不可重复读幻读事务隔离级别MVCC 底层实现原理隐式字段undo 日志Read View总结概述 MVCC(Multi-Version Concurrency Control) &#xff0c;叫做基于多版本的并发控制协议。 MVCC 是乐观锁的一种实现方式&#xff0c;它在很多情况下&#…

多线程增量下载K线数据

准备一份股票列表的CSV文件&#xff0c;文件格式如下 codenameclosecmvdate_ipo300434金石亚药12.89427982959020150424300380安硕信息19.31241993416320140128688123聚辰股份132.821114087266620191223300586美联新材20.34790882138120170104300534陇神戎发12.96389465063120…

Arduino与Proteus仿真实例-密码输入、验证与更新仿真

密码输入、验证与更新仿真 本次实例将通过4X4矩阵键盘、LCD1602、EEPROM实现一个密码输入匹配、储存、更新。 1、仿真电路原理图 在仿真电路原理图中,4X4矩阵键盘通过PCF8574 IO扩展器驱动,请参考前面文章: Arduino与Proteus仿真实例-PCF8574驱动4x4矩阵键盘仿真Arduino与…

大数据:Flume安装部署和配置

文章目录Flume 简介一&#xff0c;Flume下载和安装1&#xff09;登录[Flume官网](https://flume.apache.org/)&#xff0c;下载 apache-flume-1.9.0-bin.tar.gz2&#xff09;解压文件到 /opt 目录下3&#xff09;改名为 flume二&#xff0c;Flume配置1&#xff09;修改 /conf/ …

.Net开发——EFCore

1 EFCore是一个ORM框架 EFCore(EntityFramworkCore)是对底层ADO.NET重新封装的一个数据操作框架&#xff0c;因此ADO.NET支持的多种数据库都可以被EFCore支持。 EF Core 可用作对象关系映射程序 (O/RM)&#xff0c;这可以实现以下两点&#xff1a; 使 .NET 开发人员能够使用…

Python医学数据分析入门,推荐你学习这本书

医学生学习Python的难点通常在于 没有系统的编程教育&#xff0c;很难短时间内使用编程语言描述问题及其解答过程相关教程、案例少&#xff0c;想要练习缺少素材 所以这里就给大家推荐一本比较新比较前沿的教医学生学习Python的书《Python医学数据分析入门》 这本书的切入点为…

代码随想录——分割回文串 II

题目 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是回文。 返回符合要求的 最少分割次数 。 示例 1&#xff1a; 输入&#xff1a;s “aab” 输出&#xff1a;1 解释&#xff1a;只需一次分割就可将 s 分割成 [“aa”,“b”] 这样两个回文子…

Oracle技术分享 创建外键报错ORA-00906

问题描述&#xff1a;给表创建外键报错ORA-00906&#xff0c;具体过程如下&#xff1a; 数据库&#xff1a;oracle 11.2.0.464位 scottORCL2022-10-18 19:10:40> selectindex_name,table_name,tablespace_name,status,last_analyzed from user_indexes; INDEX_NAME TABLE…

事务【mysql】

1、事务的概念 事务指逻辑上的一组操作&#xff0c;组成这组操作的各个单元&#xff0c;要么全部成功&#xff0c;要么全部失败。 在不同的环境中&#xff0c;都可以有事务。对应在数据库中&#xff0c;就是数据库事务。 把多个操作打包成一个整体&#xff0c;要么全部都执行完…

【#HDC2022】HarmonyOS体验官活动正式开启,赶快投稿赢限量奖品吧!

1. 【活动简介】 HDC 2022 于11月4日线上线下正式开启。历时一年&#xff0c;在无数开发者的共同努力下&#xff0c;我们汇聚了HarmonyOS生态的新成果、新体验、新开放能力&#xff0c;邀你参与到HarmonyOS的每一步成长和构建中。 本次HarmonyOS体验官活动&#xff0c;将以文章…

MySQL自连接和内连接和外连接_左外连接+右外连接

自连接&#xff1a;将一张表看作两张表 练习&#xff1a;查询员工id&#xff0c;员工姓名及其管理者的id和姓名select emp.employee_id,emp.last_name,mgr.employee_id,mgr.last_name from employees emp,employees mgr where emp.manager_id mgr.employee_id;内连接 只是把左…

多肽Caerulein (desulfated)、pGlu-QDYTGWMDF-NH2、20994-83-6

Caerulein, desulfated 是脱硫后的Caerulein。Caerulein 是一种十肽&#xff0c;与胃泌素和胆囊收缩素 (CCK) 具有相同的五个羧基末端氨基酸。 Caerulein, desulfated is the desulfurated form of Caerulein. Caerulein is a decapeptide having the same five carboxyl-termi…

DevOps Master课程总结:知否知否,应是DevOps肥ITIL瘦

1.ITIL定义及挑战 ITIL即IT基础架构库(Information Technology Infrastructure Library, ITIL&#xff0c;信息技术基础架构库)由英国政府部门CCTA(Central Computing and Telecommunications Agency)在20世纪80年代末制订&#xff0c;现由英国商务部OGC(Office of Government…

Vue3 - computed 计算属性(详细教程)

简介 相信大家在 Vue2 中已经领略到了其功能&#xff0c;不再过多赘述了。 计算属性处理一些复杂的运算非常合适&#xff0c;对于任何包含响应式数据的复杂逻辑的表达式&#xff0c;都建议使用计算属性来完成&#xff0c;而不是臃肿的在模板中直接书写。 回忆 Vue2 先来看个 …

UE4插件-读取png图片

一、简介 在UE4中有多种类型的插件&#xff0c;适用于不同的场景。既可以放到引擎中还可以放到项目中&#xff0c;放到引擎中的插件可以被所有项目使用&#xff0c;放到项目中的插件只能被当前项目使用。插件的类型可以在【Edit】->【Plugins】->【New Plugin】中查看 …

06 在MSYS2中编译树莓派裸机程序,并在QEMU中运行

作者将狼才鲸创建日期2022-11-14 Gitee源码和工程地址&#xff1a;才鲸嵌入式 / 开源安防摄像机&#xff08;嵌入式软件&#xff09; CSDN文章地址&#xff1a;项目介绍&#xff1a;开源安防摄像机&#xff08;嵌入式软件&#xff09; 4&#xff09;完整的环境安装步骤 写在前…

软件产品测试的准入准出标准有哪些?

软件产品的测试并不是测试人员简单的执行测试过程便可以交付的&#xff0c;而是有着一定的标准&#xff0c;什么条件可以开始测试&#xff0c;什么时候结束测试等等也就是测试的准入准出标准。 一、软件测试的准入标准 1、开发人员编码结束并且已在开发环境中完成单元测试&a…

OpUtils局域网唤醒:远程引导计算机

局域网唤醒 &#xff08;LAN&#xff09;&#xff0c;通常称为 LAN 唤醒&#xff0c;是一种计算机网络标准&#xff0c;有助于远程启动有线和无线网络。也称为远程唤醒、LAN 唤醒、无线 LAN 唤醒或简称 WOL&#xff0c;LAN 唤醒技术可帮助网络管理员优化能源使用&#xff0c;并…