当前位置: 首页 > news >正文

30天自制操作系统(第23天)

23.1 编写malloc

参考第22天的内容,在绘制窗口前先分配了150*50个字节大小的内存,所以导致该文件经编译后有7.6k左右,能否在其中使用指针呢?当需要开辟空间时,移动指针即可。在之前的章节中也有函数memman_alloc函数可分配内存空间,所以在该节中将都用到这个函数。
按照下表对api的设计,编写a_nask.nas中的相关函数,以及增加console.c文件中对edx的判断。
memman 初始化
malloc
free
EDX=8
EBX=memman 的地址
EAX=memman 所管理的内存空间的起始地址
ECX=memman 所管理的内存空间的字节数
EDX=9
EBX=memman 的地址
ECX= 需要请求的字节数
EAX= 分配到的内存空间地址
EDX=10
EBX=memman 的地址
EAX= 需要释放的内存空间地址
ECX= 需要释放的字节数
_api_initmalloc:			; void api_initmalloc(void);PUSH 	EBXMOV 	EDX,8MOV 	EBX,[CS:0x0020] ; 初始化地址 P494页 0x0020 (DWORD) ……malloc空间的起始地址MOV 	EAX,EBX ADD		EAX,32*1024		;分配了32k内存MOV 	ECX,[CS:0x0000]SUB		ECX,EAX			;包括前32位数据(文件信息)以及32k内存INT 	0x40POP 	EBXRET_api_malloc:				;char *api_malloc(int size)PUSH	EBXMOV		EDX,9MOV		EBX,[CS:0x0020]MOV		ECX,[ESP+8]		;sizeINT		0x40POP		EBXRET_api_free:					;void api_free(char *addr, int size)PUSH	EBXMOV		EDX,10MOV		EBX,[CS:0x0020]MOV		EAX,[ESP+8]		;addrMOV		ECX,[ESP+12]	;sizeINT		0x40POP		EBXRET

23.2 画点

该节实现绘制一个点的功能,下面先介绍一下API的设计:
EDX =11
EBX = 窗口句柄
ESI = 显示位置的 x 坐标
EDI = 显示位置的 y 坐标
EAX = 色号
/*                a_nask.nas                */
_api_point:					;void api_point(int win, int x, int y, int col);PUSH	EDIPUSH	ESIPUSH	EBXMOV		EDX,11MOV		EBX,[ESP+16]	;winMOV		ESI,[ESP+20]	;xMOV		EDI,[ESP+24]	;yMOV		EAX,[ESP+28]	;colINT		0X40POP		EBXPOP		ESIPOP		EDIRET/*                console.c                */
if(edx == 11){//api_pointsht = (struct SHEET *) ebx;sht->buf[sht->bxsize * edi + esi] = eax;//修改某个点的颜色sheet_refresh(sht, esi, edi, esi + 1, edi + 1);
}

23.3 刷新窗口

考虑到每次绘制一个点都需要进行一次刷新,不如将所有点画好后刷新一次画面来的快,所以该节实现 刷新窗口的功能,下面先介绍一下API的设计:
EDX = 12
EBX = 窗口句柄
EAX = x0
ECX = y0
ESI = x1
EDI = y1
如下操作:sht = (struct SHEET *) (ebx&0xfffffffe);的目的为,窗口句柄归根到底是struct SHEET的地址,这一定是一个偶数,所以使ebx为字符串的地址进行运算。ebx&1 == 0是判断ebx作为字符串的地址,是否为空,如果为空则刷新图层。
/*                a_nask.nas                */
_api_refreshwin:			;void api_refreshwin(int win, int x0, int y0, int x1, int y1);PUSH	EDIPUSH	ESIPUSH	EBXMOV		EDX,12MOV		EBX,[ESP+16]	;winMOV		EAX,[ESP+20]	;x0MOV		ECX,[ESP+24]	;y0MOV		ESI,[ESP+28]	;x1MOV		EDI,[ESP+32]	;y1INT		0X40POP		EBXPOP		ESIPOP		EDIRET/*                console.c                */
int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax){(中略)if(edx == 1)cons_putchar(cons, eax&0xff, 1);else if(edx == 2)cons_putstr0(cons, (char*)ebx+ds_base);else if(edx == 3)cons_putstr1(cons, (char*)ebx+ds_base, ecx);else if(edx == 4)  return &(task->tss.esp0); else if(edx == 5){(中略)}else if(edx == 6){
/*这里*/sht = (struct SHEET *) (ebx&0xfffffffe);(中略)
/*这里*/if(ebx&1 == 0)
/*这里*/	sheet_refresh(sht, eax, ecx, esi + 1, edi + 1);}else if(edx == 8){//memman初始化(中略)}else if(edx == 9){//malloc(中略)}else if(edx == 10){//freeecx = (ecx+0x0f)&0xfffffff0;//所释放的内存空间的字节数memman_free((struct MEMMAN *) (ebx + ds_base), eax, ecx);}else if(edx == 11){//api_point
/*这里*/ sht = (struct SHEET *) (ebx&0xfffffffe);sht->buf[sht->bxsize * edi + esi] = eax;
/*这里*/ if(ebx&1 == 0)//当ebx的最低位为0,也就是没有字符串需要打印时,刷新图层
/*这里*/	sheet_refresh(sht, esi, edi, esi + 1, edi + 1);}else if(edx == 12){
/*这里*/ sht = (struct SHEET *) ebx;
/*这里*/ sheet_refresh(sht, eax, ecx, esi, edi);}return 0;
}

23.4 画直线

在窗口上画直线: EDX = 13   EBX = 窗口句柄   EAX = x0   ECX = y0   ESI = x1   EDI = y1   EBP = 色号。考虑画的是直线,如果点间隙较大则会变成虚线,较小则会可能出现在一个坐标上多次花点浪费时间,所以选择将坐标跨度较大的间隙分为1024,直接看代码。
/*                a_nash.nas                */
_api_linewin:	;void api_linewin(int win, int x0, int y0, int x1, int y1, int col);PUSH	EDIPUSH	ESIPUSH	EBPPUSH	EBXMOV		EDX,13MOV		EBX,[ESP+20]	;winMOV		EAX,[ESP+24]	;x0MOV		ECX,[ESP+28]	;y0MOV		ESI,[ESP+32]	;x1MOV		EDI,[ESP+36]	;y1MOV		EBP,[ESP+40]	;colINT		0X40POP		EBXPOP		EBPPOP		ESIPOP		EDIRET/*                console.c                */
if(edx == 13){sht = (struct SHEET *) (ebx&0xfffffffe);hrb_api_linewin(sht, eax, ecx, esi, edi, ebp);if(ebx&1 == 0)//当ebx的最低位为0,也就是没有字符串需要打印时,刷新图层sheet_refresh(sht, eax, ecx, esi, edi);
}void hrb_api_linewin(struct SHEET *sht, int x0, int y0, int x1, int y1,int col){int i, x, y, len, dx, dy;dx = x1-x0;dy = y1-y0;x = x0<<10;y = y0<<10;if(dx < 0)dx = -dx;if(dy < 0)dy = -dy;if(dx >= dy){len = dx+1;if(x0 > x1)dx = -1024;else dx = 1024;if(y0 <= y1)dy = ((y1-y0+1)<<10)/len;else dy = ((y1-y0-1)<<10)/len;//-(y0-y1+1) = y1-y0-1}else{len = dy+1;if(y0 > y1)dy = -1024;else dy = 1024;if(x0 <= x1)dx = ((x1-x0+1)<<10)/len;else dx = ((x1-x0-1)<<10)/len;}for(i = 0; i < len; i++){sht->buf[(y>>10)*sht->bxsize+(x>>10)] = col;x += dx;y += dy;}return;
}

23.5 关闭窗口

关闭窗口:EDX=14   EBX= 窗口句柄。sheet_free()函数是释放已使用的图层。
/*                a_nask.nas                */
_api_closewin:				;void api_closewin(int win);PUSH	EBXMOV 	EDX,14MOV		EBX,[ESP+8]		;winINT		0X40POP		EBXRET/*                console.c                */
if(edx == 14){//关闭窗口sheet_free((struct SHEET *) ebx);
}

23.6 键盘输入API

该节主要实现的功能为:当按下回车键时关闭lines窗口。
键盘输入:EDX = 15   EAX = 0…… 没有键盘输入时返回 -1 ,不休眠
                                            = 1……休眠直到发生键盘输入
                                    EAX = 输入的字符编码
参照console_task()函数编写函数,当eax!=0时则进入休眠状态,否则没有键盘输入返回值eax为-1(reg[7]存放的是寄存器eax)。当输入键盘数据时,则更新eax寄存器中的值。
为了设置定时器我们需要 timer的地址,不过这是 console_task 中的变量,hrb_api是无法获取的,所以在CONSOLE结构体中增加元素struct TIMER *timer; 因此还修改了 console_task ,去掉 timer 变量,以 cons.timer 取而代之。
/*                a_nask.nas                */
_api_getkey:				;int api_getkey(int mode);MOV		EDX,15MOV		EAX,[ESP+4]INT		0X40RET/*                console.c                */
if(edx == 15){for(;;){io_cli();if(fifo32_status(&task->fifo) == 0){if(eax != 0)task_sleep(task);//休眠else{//没有键盘输入时返回-1,不休眠io_sti();reg[7] = -1;return 0;}}i = fifo32_get(&task->fifo);if(i <= 1){//光标/*应用程序运行时不需要显示光标,因此总是将下次显示用的值置为1*/timer_init(cons->timer, &task->fifo, 1);timer_settime(cons->timer, 50);}if(i == 2)cons->cur_c = COL8_FFFFFF;/*光标ON */if(i == 3)cons->cur_c = -1;/*光标OFF */if(256 <= i && i <= 511){reg[7] = i-256;return 0;}}
}

23.7 强制结束并关闭窗口

在运行 walk.hrb lines.hrb 时,如果不按回车键结束,而是按Shift+F1强制结束程序的话,窗口就会残留在画面上。
首先,在 struct SHEET 中添加一个用来存放 task的成员,当应用程序结束时,查询所有的图层,如果图层的 task为将要结束的应用程序任务,则关闭该图层。
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline){int segsiz, datsiz, esp, dathrb;
/*这里*/struct SHEET *sht;
/*这里*/struct SHTCTL *shtctl;(中略)if (finfo != 0) {/* 找到了与字符串相同的文件 */p = (char *) memman_alloc_4k(memman, finfo->size);file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00));if (finfo->size >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00){(中略)start_app(0x1b, 1003 * 8, esp, 1004*8, &(task->tss.esp0));
/*从这里开始*/shtctl = (struct SHTCTL *) *((int *) 0x0fe4);/*从这里开始*/for(i = 0; i <  MAX_SHEETS; i++){sht = &(shtctl->sheets0[i]);if(sht->flags != 0 && sht->task == task)sheet_free(sht);
/*到这里结束*/}memman_free_4k(memman, (int) q, segsiz);}elsecons_putstr0(cons, ".hrb file format error.\n");memman_free_4k(memman, (int) p, finfo->size);cons_newline(cons);return 1;}return 0;
}

相关文章:

30天自制操作系统(第23天)

23.1 编写malloc 参考第22天的内容&#xff0c;在绘制窗口前先分配了150*50个字节大小的内存&#xff0c;所以导致该文件经编译后有7.6k左右&#xff0c;能否在其中使用指针呢&#xff1f;当需要开辟空间时&#xff0c;移动指针即可。在之前的章节中也有函数memman_alloc函数可…...

基于Rust语言,和WebAssembly技术,与JavaScript结合,的具体应用场景

基于Rust语言与WebAssembly&#xff08;Wasm&#xff09;技术并与JavaScript结合&#xff0c;可以应用于多个场景&#xff0c;特别是在需要高性能和/或低级系统访问的情况下。下面是一些具体的应用场景&#xff1a; 性能密集型任务: Rust加上Wasm适合执行计算密集型任务&#x…...

【MATLAB源码-第154期】基于matlab的OFDM系统多径信道下块状和梳妆两种导频插入方式误码率对比仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 OFDM&#xff08;Orthogonal Frequency Division Multiplexing&#xff0c;正交频分复用&#xff09;是一种高效的无线信号传输技术&#xff0c;广泛应用于现代通信系统&#xff0c;如Wi-Fi、LTE和5G。OFDM通过将宽带信道划分…...

Linux 下 socket 编程介绍及 TCP 客户端与服务端创建示例

目录 socket 编程接口TCP 服务端TCP 客户端更多内容 本文介绍了 Linux 下的 socket 编程&#xff0c;及总结了使用 socket 接口实现 TCP 服务端和客户端的示例代码。 socket 编程接口 socket() 函数&#xff1a;用于创建一个新的 socket 描述符&#xff1a; int socket(int …...

JetBrains Gateway Github Copilot 客户端插件和主机插件

JetBrains Gateway可以通过插件支持Github Copilot&#xff08;需另行注册&#xff09;。 需要安装插件 客户端&#xff0c;而非插件 主机&#xff0c;如图所示&#xff1a; 大概是因为代码显示在客户端&#xff08;运行在本地的IDE&#xff09;&#xff1f;...

【web APIs】3、(学习笔记)有案例!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、概念其他事件页面加载事件元素滚动事件页面尺寸事件 元素尺寸与位置 二、案例举例电梯导航 前言 掌握阻止事件冒泡的方法理解事件委托的实现原理 一、概念…...

使用css reset 还是使用Normalize.css

文章目录 使用css reset 还是使用Normalize.cssCSS Reset:Normalize.css:总结Normalize.css 的使用&#xff08;例如Vue 3.0 和 Vue CLI 4.x 项目&#xff09;1.安装2.main.js 中导入3.测试引用是否成功。 使用css reset 还是使用Normalize.css 使用 CSS Reset 还是 Normalize…...

英语中的提问方式(问法)(bug提问、bug描述)

文章目录 英语提问方式一、单词、短语、句子的意思1.1 提问单词的意思1.2 提问短语的意思1.3 提问句子的意思 二、在编程中提问2.1 提问bug2.2 请求代码帮助 如何提出反问句1. 构建反问句的基本结构2. 提问反问句的方法3. 理解反问句的意图 在口语中提问&#xff1a;确保清晰度…...

xss.haozi.me靶机练习

目录 第零关&#xff1a; 第一关&#xff1a; 第二关&#xff1a; 第三关&#xff1a; 第四关&#xff1a; 第五关&#xff1a; 第六关&#xff1a; 第七关&#xff1a; 第八关&#xff1a; 第九关&#xff1a; 第十关&#xff1a; 第十一关&#xff1a; 第十二关…...

2.1 mov、add和sub加减指令实操体验

汇编语言 1. mov操作 1.1 mov移动值 mov指令把右边的值移动到左边 mount c d:masm c: debug r ax 0034 r 073f:0100 mov ax,7t1.2 mov移动寄存器的值 把右边寄存器的值赋值给左边的寄存器 a 073f:0105 mov bx,axt1.3 mov高八位&#xff08;high&#xff09;和低八位&am…...

计算机设计大赛 深度学习机器视觉车道线识别与检测 -自动驾驶

文章目录 1 前言2 先上成果3 车道线4 问题抽象(建立模型)5 帧掩码(Frame Mask)6 车道检测的图像预处理7 图像阈值化8 霍夫线变换9 实现车道检测9.1 帧掩码创建9.2 图像预处理9.2.1 图像阈值化9.2.2 霍夫线变换 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分…...

中间件安全(概述)有中间件的各类链接和官网信息和漏洞库以及配置问题和开源工具

分类主要包括Apache、IIS、Tomcat、weblogic、websphere、Jboss等相关的技术知识和实践。 以Apache为例讲一讲如何保证中间件安全 中间件安全是指保护中间件软件和服务的安全性&#xff0c;防止被恶意攻击或者滥用。中间件软件是指在操作系统和应用程序之间提供通信和集成功能…...

Unity铰链四杆机构设计和运动仿真

一、效果图 设定好各边长度和转速后&#xff0c;点击【设置并启动】&#xff0c;自动生成一个机构模型&#xff0c;并按照原理进行运转 二、铰链四杆机构介绍 机架&#xff1a;A和D是固定位置&#xff0c;叫做机架。 曲柄&#xff1a;B点绕A点旋转&#xff0c;构成曲柄。 连…...

Python爬虫——解析常用三大方式之Xpath

目录 Xpath 安装xpath 安装lxml库 导入lxml库 解析本地文件 etree.parse&#xff08;&#xff09; 解析服务器响应文件 etree.HTML() xpath基本语法 小案例&#xff1a;获取百度首页的百度一下 大案例&#xff1a;爬取站长素材图片 总结 Xpath 安装xpath 首先要学会安…...

C#判断DataTable1 A列的集合是否为DataTable2 B列的集合的子集

DataSet ds2 (DataSet)res2.Anything; // 检查 集合B是否为集合A的子集 var table1MaterialCodes ds.Tables[2].AsEnumerable().Select(row > row["Code"]).ToList(); //DataSet1 表Code列集合A var table2MaterialCodes ds2.Tables[0].AsEnumerable().Selec…...

VirtualBox 桥接网卡 未指定 “未能启动虚拟电脑Ubuntu,由于下述物理网卡未找到:”

解决办法&#xff0c;安装虚拟网卡&#xff0c;win11查找方式&#xff1a;控制面板→网络和共享中心→更改适配器设置 此时出现下面情况就算安装成功 但是如果报错&#xff1a;找不到指定的模块 则按下面步骤删除干净垃圾重新上面操作 先安装CCleaner, 链接:CCleaner Makes Y…...

基于yolov5的电瓶车和自行车检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的电瓶车和自行车检测系统_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的电瓶车和自行车检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的项目&#xff0c;包括代码&#xff0c;数据集&#xff0c;训练好的模型…...

vscode如何远程到linux python venv虚拟环境开发?(python虚拟环境、vscode远程开发、vscode远程连接)

文章目录 1. 安装VSCode2. 安装扩展插件3. 配置SSH连接4. 输入用户名和密码5. 打开远程文件夹6. 创建/选择Python虚拟环境7. 安装Python插件 Visual Studio Code (VSCode) 提供了一种称为 Remote Development 的功能&#xff0c;允许用户在远程系统、容器或甚至 Windows 子系统…...

蓝桥杯第十二届电子类单片机组程序设计

目录 前言 蓝桥杯大赛历届真题_蓝桥杯 - 蓝桥云课&#xff08;点击查看&#xff09; 单片机资源数据包_2023&#xff08;点击下载&#xff09; 一、第十二届比赛原题 1.比赛题目 2.题目解读 蓝桥杯第十四届电子类单片机组程序设计_蓝桥杯单片机哪一届最难-CSDN博客 二、…...

基于springboot+vue的工作流程管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...