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;
}

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

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

相关文章

php源码 单色bmp图片取模工具 按任意方式取模 生成字节数组 自由编辑点阵

http://2.wjsou.com/BMP/index.html 想试试chatGPT4生成&#xff0c;还是要手工改 php 写一个网页界面上可以选择一张bmp图片&#xff0c;界面上就显示这张bmp图片&#xff0c; 点生成取模按钮&#xff0c;在图片下方会显示这张bmp图片的取模数据。 取模规则是按界面设置的&a…

Linux 的交换空间(swap)是什么?有什么用?

目录 swap是什么&#xff1f;swap有什么用&#xff1f;swap使用典型场景如何查看你的系统是否用到交换空间呢&#xff1f;查看系统中swap in/out的情况 swap是什么&#xff1f; swap就是磁盘上的一块区域。它和Windows系统中的交换文件作用类似&#xff0c;但是它是一段连续的…

03、MongoDB -- MongoDB 权限的设计

目录 MongoDB 权限的设计演示前准备&#xff1a;启动 mongodb 服务器 和 客户端 &#xff1a;1、启动单机模式的 mongodb 服务器2、启动 mongodb 的客户端 MongoDB 权限的设计1、MongoDB 的每个数据库都可以保存用户&#xff0c;不止admin数据库可以保存用户。2、保存用户的数据…

Linux 学习笔记(8)

八、 启动引导 1 、 Linux 的启动流程 1) BIOS 自检 2) 启动 GRUB/LILO 3) 运行 Linux kernel 并检测硬件 4) 挂载根文件系统 5) 运行 Linux 系统的第一个进程 init( 其 PID 永远为 1 &#xff0c;是所有其它进程的父进程 ) 6) init 读取系统引导配置文件…

GD25Q32驱动

GD25Q32是一款基于SPI的Flash芯片&#xff0c;容量为32/84M bytes。它的引脚如下&#xff1a; 该芯片支持多种SPI操作方式&#xff0c;包括&#xff1a;Standard SPI(标准SPI)、Dual SPI(双线 SPI)和Quad SPI(四线 SPI) 。有关SPI的介绍可以参考&#xff1a; SPI通信原理-CSDN…

flutter 文字一行显示,超出换行

因为app有多语言&#xff0c;中文和其他语言长度不一致&#xff0c;可能导致英文会很长。 中文样式 英文样式 代码 Row(mainAxisAlignment: MainAxisAlignment.end,crossAxisAlignment: CrossAxisAlignment.end,children: [Visibility(visible: controller.info.fee ! null,ch…

探寻2024年国内热门低代码平台排行!| 功能特点一览

低代码开发是一项革命性的技术&#xff0c;主要目的是尽量避免程序研发的复杂性&#xff0c;让外行开发者也能加入到应用程序的搭建中。低代码平台的核心概念和构成部分通常包括用户界面和拖拽设计、预构件和模块、自动化工作内容与数据库集成和扩展应用&#xff0c;应用低代码…

web前端css基本内容

web前端css 当我们用html的语法给内容规划布局样式时&#xff0c;可能会出现许多个相似的内容需要运用同一种样式&#xff0c;复制粘贴太麻烦而且如果后期要改动的话比如把许多个地方从红色改成蓝色&#xff0c;就需要一个一个改了&#xff0c;这时候就需要引入css来操作了 把…

java-使用jacob删除指定文件夹的邮件

总结见文章最后,具体代码如下: ActiveXComponent outlook = new ActiveXComponent("Outlook.Application");Dispatch myNamespace = Dispatch.call(outlook, "GetNamespace", "MAPI").toDispatch();//指定搜索特定的文件Dispatch allFolders =…

我耀学IT—day05-Bootstrap下拉菜单与导航

一、Bootstrap5 下拉菜单 下拉菜单是可切换的&#xff0c;是以列表格式显示链接的上下文菜单。 例&#xff1a; <div class"dropdown"><button type"button" class"btn btn-primary dropdown-toggle" data-bs-toggle"dropdown&…

U盘弹出提示“该设备正在使用中”:原因与解决方案

在日常使用U盘时&#xff0c;我们可能会遇到一个问题&#xff1a;当尝试安全弹出U盘时&#xff0c;系统提示“该设备正在使用中”。这种情况可能会让用户感到困惑&#xff0c;担心数据是否安全或是否会导致U盘损坏。本文旨在探讨这一现象背后的原因&#xff0c;并提供相应的解决…

【前端素材】推荐优质后台管理系统网页Stisla平台模板(附源码)

一、需求分析 1、系统定义 后台管理系统是一种用于管理和控制网站、应用程序或系统的管理界面。它通常被设计用来让网站或应用程序的管理员或运营人员管理内容、用户、数据以及其他相关功能。后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;通常由管理员使…

铅冶炼作业VR虚拟现实互动培训平台降低实操风险

在钢铁工业中&#xff0c;焦炉作业是一个关键的环节&#xff0c;也是一项技术要求高、操作复杂的任务。传统焦炉作业的培训通常需要在实际的焦炉上进行&#xff0c;这不仅对学员的身体素质和心理素质提出了较高的要求&#xff0c;而且也存在一定的安全风险。基于VR虚拟现实制作…

React富文本编辑器开发(三)

现在我们的编辑器显示的内容很单一&#xff0c;这自然不是我们的目标&#xff0c;让呈现的内容多元化是我们的追求。这就需要让编辑器能够接收多元素的定义。从初始数据的定义我们可以推断数据的格式远不止一种&#xff0c;那么其它类型的数据如何定义及呈现的呢&#xff0c;我…

基于单片机的AGV机器人设计的设计要求

基于单片机的AGV机器人设计的设计要求 1. 引言 本设计要求旨在设计一种基于单片机的自动导航车&#xff08;AGV&#xff09;机器人。AGV机器人可以在工厂、仓库等场景中进行自动导航、物料搬运等任务。本设计要求包括机器人的硬件设计要求和软件设计要求两个方面。 2. 硬件设…

(Aliyun AI ACP 02)阿里云人工智能产品体系

文章目录 阿里云人工智能工程师ACP认证考试知识点辅助阅读&#xff08;Aliyun AI ACP 02&#xff09;阿里云人工智能产品体系引言阿里云AI产品总体架构基础设施层&#xff1a;平台层&#xff1a;算法与模型层&#xff1a;应用层&#xff1a;组成部分详述&#xff1a;PAI产品家族…

手把手教你免费用Flashduty做消息通知

为什么需要消息通知&#xff1f; 如果有重要的情况发生&#xff0c;希望能通过各种媒介通知我们。可以举几个例子&#xff1a; 家里燃气费没有了&#xff0c;希望能有短信或者app通知api频繁500报错&#xff0c;希望及时感知&#xff0c;及时修复公司网站是https自签名证书&a…

白话大模型① :AI分析能做什么?在实际落地中会碰到什么问题?

白话大模型系列共六篇文章&#xff0c;将通俗易懂的解读大模型相关的专业术语。本文为第一篇&#xff1a;AI分析能做什么&#xff1f;在实际落地中会碰到什么问题&#xff1f; 作者&#xff1a;星环科技 人工智能产品部 我们使用一个简单的应用实例来解析人工智能分析都在做什…

若依框架使用mars3d的环境配置,地球构建

因项目需要&#xff0c;原本使用过的cesium依赖&#xff0c;现在想使用火星科技mars3d的一些功能&#xff0c;所以需要引入mars3d依赖&#xff0c;整个过程非常的坎坷&#xff0c;以至于我都不知道到底是哪些部分是标准的。。。先把我认为对的记录一下&#xff1a; 1.vue.conf…

[渗透教程]-200-网络安全基本概念

文章目录 1.0专业术语1.1资产1.2网络安全 (cyber security)1.3 网络空间 (cyberspace)1.4安全的属性1.5 安全策略1.6 威胁模型1.7 威胁模型1.8 DREAD模型1.9 OCTAVE模型1.10 国内的安全2.安全策略(Security Policy)3.安全机制(Security Mechanism)4. 安全防护模型