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.pswp.cn/news/714540.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/714540.shtml
英文地址,請注明出處:http://en.pswp.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. 安全防護模型