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

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

28.1 alloca

__alloca 会在下述情况下被 C 语言的程序调用(采用 near-CALL 的方式)。
1、要执行的操作从栈中分配 EAX 个字节的内存空间( ESP -= EAX;
2、要遵守的规则不能改变 ECX EDX EBX EBP ESI EDI的值(可以临时改变它们的值,但要使用 PUSH/POP 来复原)
RET 返回的地址保存在了ESP(“RET”指令实际上相当于“POP EIP”,“POP EIP”实际上又相当于下面两条指令:MOV EIP,[ESP]    ADD ESP,4)。为实现类似RET功能指令,所以编写了如下 __alloca函数指令。
__alloca:
        SUB  ESP,EAX
        ADD  ESP,4
        JMP  DWORD [ESP+EAX-4] ; 代替 RET
注:C语言中,在函数外部声明的变量和带static的变量一样,都会被解释为DB和RESB;在函数内部不带static声明的变量则会从栈中分配空间。

28.2 文件操作API 

需要实现的功能:打开、定位、读取、写入和关闭文件。思路:打开文件时需要指定文件名,如果打开成功,操作系统将返回文件句柄。在随后的操作中,只要提供这个文件句柄就可以进行读写操作了,操作结束后将文件关闭。读取和写入API基本上需要指定需要读取(写入)的数据长度以及内存地址,文件的内容会被传送至内存(写入操作时是由内存传送至文件)。
打开文件
关闭文件
文件定位
获取文件大小
文件读取
EDX=21
EBX= 文件名
EAX= 文件句柄(为 0 时表示打开失败)(由操作系统返回)
EDX=22
EAX= 文件句柄
EDX=23
EAX= 文件句柄
ECX= 定位模式
        =0:定位的起点为文件开头
        =1:定位的起点为当前的访问位置
        =2:定位的起点为文件末尾
EBX= 定位偏移量
EDX=24
EAX= 文件句柄
ECX= 文件大小获取模式
       =0:普通文件大小
       =1:当前读取位置从文件开头起算的偏移量
       =2:当前读取位置从文件末尾起算的偏移量
EAX= 文件大小(由操作系统返回)
EDX=25
EAX= 文件句柄
EBX= 缓冲区地址
ECX= 最大读取字节数
EAX= 本次读取到的字节数(由操作系统返回)
/*                    bootpack.h                    */
struct TASK {(中略)int ds_base, cons_stack;struct FILEHANDLE *fhandle; /*从此开始*/int *fat; /*到此结束*/
};
struct FILEHANDLE { /*从此开始*/char *buf;int size;int pos;
}; /*到此结束*//*                    console.c                    */
void console_task(struct SHEET *sheet, int memtotal)
{(中略)struct FILEHANDLE fhandle[8];(中略)for (i = 0; i < 8; i++) fhandle[i].buf = 0; /*未使用标记*/task->fhandle = fhandle;task->fat = fat;(中略)
}if (finfo->size >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00) {//cmd_app代码片段(中略)start_app(0x1b, 0 * 8 + 4, esp, 1 * 8 + 4, &(task->tss.esp0));(中略)for (i = 0; i < 8; i++) { /*将未关闭的文件关闭*/ /*从此开始*/if (task->fhandle[i].buf != 0) {memman_free_4k(memman, (int) task->fhandle[i].buf, task->fhandle[i].size);task->fhandle[i].buf = 0;}} /*到此结束*/(中略)
}int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax){(中略)struct FILEINFO *finfo;struct FILEHANDLE *fh;struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;(中略)
/*开始*/}else if(edx == 21){//打开文件for(i = 0; i < 8; i++){if(task->fhandle[i].buf == 0)break;}fh = &task->fhandle[i];reg[7] = 0;if(i < 8){finfo = file_search((char*)ebx+ds_base, (struct FILEINFO*)(ADR_DISKIMG+0x002600), 224);if(finfo != 0){reg[7] = (int)fh;fh->buf = (char *) memman_alloc_4k(memman, finfo->size);fh->size = finfo->size;fh->pos = 0;file_loadfile(finfo->clustno, finfo->size, fh->buf, task->fat, (char *)(ADR_DISKIMG+0x003e00));}}}else if(edx == 22){//关闭文件fh = (struct FILEHANDLE*)eax;memman_free_4k(memman, (int)fh->buf, fh->size);//与打开文件操作中的memman_alloc_4k对应fh->buf = 0;}else if(edx == 23){//文件定位fh = (struct FILEHANDLE*)eax;if(ecx == 0){//定位的起点为文件开头fh->pos = ebx;}else if(ecx == 1){//定位的起点为当前的访问位置fh->pos += ebx;}else if(ecx == 2){//定位的起点为文件末尾fh->pos = fh->size + ebx;}if(fh->pos < 0)fh->pos = 0;if(fh->pos > fh->size)fh->pos = fh->size;}else if(edx == 24){//获取文件大小fh = (struct FILEHANDLE*)eax;if(ecx == 0){//普通文件大小reg[7] = fh->size;}else if(ecx == 1){//当前读取位置从文件开头起算的偏移量reg[7] = fh->pos;}else if(ecx == 2){//当前读取位置从文件末尾起算的偏移量reg[7] = fh->pos - fh->size;}}else if(edx == 25){//文件读取,写入到ebx缓存区中fh = (struct FILEHANDLE*)eax;for(i = 0; i < ecx; i++){if(fh->pos == fh->size)break;*((char *) ebx + ds_base + i) = fh->buf[fh->pos];fh->pos++;}reg[7] = i;
/*结束*/}return 0;
}

28.3 命令行API 

需要实现的功能:在用户输入“type ***.nas”这样的命令时获取后面的文件名。
获取命令行
EDX=26
EBX= 存放命令行内容的地址
ECX= 最多可存放多少字节
EAX= 实际存放了多少字节(由操作系统返回)
/*                    a_nask.nas                    */
_api_cmdline: ; int api_cmdline(char *buf, int maxsize);PUSH EBXMOV EDX,26MOV ECX,[ESP+12] ; maxsizeMOV EBX,[ESP+8] ; bufINT 0x40POP EBXRET
/*                    bootpack.h                    */
struct TASK {(中略)char *cmdline;
};/*                    console.c                    */
void console_task(struct SHEET *sheet, int memtotal)
{(中略)task->cons = &cons;task->cmdline = cmdline; /*这里!*/(中略)
}int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
{(中略)} else if (edx == 26) {i = 0;for (;;) {*((char *) ebx + ds_base + i) = task->cmdline[i];if (task->cmdline[i] == 0) {break;}if (i >= ecx) {break;}i++;}reg[7] = i;}return 0;
}

相关文章:

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

28.1 alloca __alloca 会在下述情况下被 C 语言的程序调用&#xff08;采用 near-CALL 的方式&#xff09;。 1、要执行的操作从栈中分配 EAX 个字节的内存空间&#xff08; ESP - EAX; &#xff09; 2、要遵守的规则不能改变 ECX 、 EDX 、 EBX 、 EBP 、 ESI 、 EDI的值&am…...

Nginx启动服务

Nginx启动服务 一、启动前置 下载地址 如已安装Docker&#xff0c;下一步拉取Nginx最新的Docker镜像&#xff1a; docker pull nginx:latest查看拉取下来的镜像&#xff1a; docker images二、启动服务 创建Docker容器&#xff1a; docker run --name {projectname} -p 80…...

coqui-ai/TTS 案例model文件

GitHub - coqui-ai/TTS: &#x1f438;&#x1f4ac; - a deep learning toolkit for Text-to-Speech, battle-tested in research and production Coqui AI的TTS是一款开源深度学习文本转语音工具&#xff0c;以高质量、多语言合成著称。它提供超过1100种语言的预训练模型库&…...

如何利用API接口进行高效的商品变体管理?

要利用API接口进行高效的商品变体管理&#xff0c;您需要执行一系列策略和技术步骤来确保数据的准确性和实时性。以下是详细的指南&#xff1a; 1. 确定变体管理需求 分析产品&#xff1a;识别具有变体的产品&#xff0c;并明确这些变体的属性&#xff08;如尺寸、颜色、材质…...

扼杀网络中的环路:STP、RSTP、MSTP

目录 前言&#xff1a; 一、STP&#xff08;Spanning Tree Protocol&#xff09; 1.1 STP功能 1.2 STP应用 二、RSTP&#xff08;Rapid Spanning Tree Protocol&#xff09; 2.1 RSTP功能 2.2 RSTP应用 三、MSTP&#xff08;Multiple Spanning Tree Protocol&#xff0…...

青少年如何从零开始学习Python编程?有它就够了!

文章目录 写在前面青少年为什么要学习编程 推荐图书图书特色内容简介 推荐理由粉丝福利写在最后 写在前面 本期博主给大家带来一本非常适合青少年学习编程的图书&#xff0c;快来看看吧~ 青少年为什么要学习编程 青少年学习编程&#xff0c;就好比在他们年轻时就开始掌握一种…...

触发HTTP preflight预检及跨域的处理方法

最近在做需求的过程中&#xff0c;遇到了很多跨域和HTTP预检的问题。下面对我所遇到过的HTTP preflight和跨域的相关问题进行总结&#xff1a; 哪些情况会触发HTTP preflight preflight属于cors规范的一部分&#xff0c;在有跨域的时候&#xff0c;在一定情况下会触发preflig…...

【算法可视化】搜索算法专题

运行平台 Algorithm Visualizer 选数 [NOIP2002 普及组] 选数 // 导入可视化库 { const { Tracer, Array1DTracer, LogTracer, Layout, VerticalLayout } require(algorithm-visualizer); // }const N 4, K 3; //从包含4个元素的集合中选出3个数 let ans 0 //方案数 co…...

编写dockerfile挂载卷、数据容器卷

编写dockerfile挂载卷 编写dockerfile文件 [rootwq docker-test-volume]# vim dockerfile1 [rootwq docker-test-volume]# cat dockerfile1 FROM centosVOLUME ["volume01","volume02"]CMD echo "------end------" CMD /bin/bash [rootwq dock…...

理解OAuth 2.0

OAuth是一个关于授权&#xff08;authorization&#xff09;的开放网络标准&#xff0c;在全世界得到广泛应用&#xff0c;目前的版本是2.0版。 本文对OAuth 2.0的设计思路和运行流程&#xff0c;做一个简明通俗的解释&#xff0c;主要参考材料为RFC 6749。 一、应用场景 为了…...

8. Go实现Gin服务优雅关机与重启

文章目录 优雅关机优雅重启 无论是优雅关机还是优雅重启归根结底都是通过监听特定系统信号&#xff0c;然后执行一定的逻辑处理保障当前系统正在处理的请求被正常处理后再关闭当前进程。 优雅关机 优雅关机就是服务端关机命令发出后不是立即关机&#xff0c;而是等待当前还在…...

SQL 注入攻击 - cookie base64编码注入

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、Base64编码介绍 原理 Base64编码的原理是将三个字节的二进制数据(共24位)转换成四个ASCII字符。由于每个ASCII字符可以表示64种状态(2^6),刚好可以用来表示24位二进制数…...

Outlook邮箱后缀如何修改?怎么添加后缀?

Outlook邮箱后缀是什么&#xff1f;Outlook邮箱后缀可以改吗&#xff1f; Outlook邮箱广泛应用于企业和个人用户之间。在使用过程中&#xff0c;有时我们可能会因为某些原因需要修改Outlook邮箱后缀。那么&#xff0c;Outlook邮箱后缀如何修改呢&#xff1f;下面&#xff0c;A…...

[LeetBook]【学习日记】图书整理 II——用两个栈实现队列

题目 图书整理 II 读者来到图书馆排队借还书&#xff0c;图书管理员使用两个书车来完成整理借还书的任务。书车中的书从下往上叠加存放&#xff0c;图书管理员每次只能拿取书车顶部的书。排队的读者会有两种操作&#xff1a; push(bookID)&#xff1a;把借阅的书籍还到图书馆。…...

5G智能制造食品工厂数字孪生可视化平台,推进食品行业数字化转型

5G智能制造食品工厂数字孪生可视化平台&#xff0c;推进食品行业数字化转型。随着科技的飞速发展&#xff0c;食品工业正迎来一场前所未有的数字化转型。在这场转型中&#xff0c;5G智能制造工厂数字孪生可视化平台发挥着至关重要的作用。它不仅提高了生产效率&#xff0c;降低…...

一个系列很多样式的wordpress外贸建站模板

菌菇干货wordpress跨境电商模板 食用菌、羊肚菌、牛肝菌、香菇、干黄花菜、梅干菜、松茸wordpress跨境电商模板。 https://www.jianzhanpress.com/?p3946 餐饮调味wordpress跨境电商模板 豆制品、蛋黄糖、烘焙、咖啡、调料、调味酱、餐饮调味wordpress跨境电商模板。 http…...

Wireshark_labs TCP

在本实验中&#xff0c;我们将详细研究著名的TCP协议的行为。我们将通过从您的电脑向远程服务器传输一份150KB 的文件(一份Lewis Carrol 的“爱丽丝梦游仙境”文本)&#xff0c; 并分析TCP传输内容的发送和接收过程来实现。我们将研究TCP对序列和确认号的使用&#xff0c;以提供…...

Linux程序崩溃调试

一、简单点的 编译时主动带-g&#xff0c;生成的程序带调试信息&#xff0c;而且开启生成dump文件&#xff0c;这时候可以使用core dump来调试程序&#xff0c;定位问题。可以参考&#xff1a;linux 程序crash 调试、原因分析及问题定位-CSDN博客 二、稍微复杂点 假设生成的可执…...

Day37 socket、TCP、UDP

socket类型 流式套接字(SOCK_STREAM) TCP 提供了一个面向连接、可靠的数据传输服务&#xff0c;数据无差错、无重复的发送且按发送顺序接收。内设置流量控制&#xff0c;避免数据流淹没慢的接收方。数据被看作是字节流&#xff0c;无长度限制。 数据报套接字(SOCK_DGRAM) UD…...

从 Language Model 到 Chat Application:对话接口的设计与实现

作者&#xff1a;网隐 RTP-LLM 是阿里巴巴大模型预测团队开发的大模型推理加速引擎&#xff0c;作为一个高性能的大模型推理解决方案&#xff0c;它已被广泛应用于阿里内部。本文从对话接口的设计出发&#xff0c;介绍了业界常见方案&#xff0c;并分享了 RTP-LLM 团队在此场景…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机&#xff0c;交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息&#xff0c;系统版本&#xff1a;Ubuntu22.04.5 LTS&#xff1b;内核版本…...

书籍“之“字形打印矩阵(8)0609

题目 给定一个矩阵matrix&#xff0c;按照"之"字形的方式打印这个矩阵&#xff0c;例如&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为&#xff1a;1&#xff0c;…...