30天自制操作系统——第十九天系统调用(API)

本文介绍了如何在30天自制操作系统项目中实现系统调用,包括显示单个字符的API、结束应用程序的方法以及创建不随操作系统版本改变的API。通过中断、异常和自陷等方式,使得CPU在用户模式和内核模式间切换,详细讲解了调用过程和代码实现。
摘要由CSDN通过智能技术生成

系统调用

API(application program interface)即应用系统对操作系统功能的调用,也可以称为系统调用(system call)。

今天我们就来实现系统调用的功能,我们先来思考一下WIN10系统是如何实现系统调用的呢?

下图是简化版的Windows系统架构图:

在这里插入图片描述

Windows计算机中处理器有两种模式,分别为用户模式(用户态、目态)和内核模式(核心态、内核态、管态、系统模式、管理模式)。在用户模式下,处理器运行用户进程,不能使用特权指令,其中特权指令是指具有特殊权限的指令,一般不直接给用户使用,比如开/关中断指令、内存清零指令、停机指令等。而在内核模式下,处理器运行内核代码,可以使用特权指令。

在WIN10系统中,用户应用程序是通过子系统DLL来调用本地Windows服务的。Windows为用户模式中的应用程序提供一个虚拟地址块,被称为应用程序的用户空间。而应用程序不能直接访问的其余大块的地址被称为系统空间(内核空间)。

实现系统调用,我们需要CPU从用户空间进入到系统空间执行。而使CPU进入系统空间执行,有三种方式:

1.中断:当有来自外部设备的中断请求到来时,CPU会自动转入系统空间执行。(被动)

2.异常:当有执行指令发生异常时,CPU会进入系统空间执行。(被动)

3.自陷(陷入、陷阱):CPU通过自陷指令进入系统空间执行,自陷指令的执行相当于子程序调用,系统调用一般都是通过自陷指令实现的。(主动)

这里我们也是使用类似自陷的方式,来实现系统调用。

显示单个字符的API

我们先来通过API显示单个字符,实现这个功能我们先把需要显示字符编码存入寄存器,然后再让应用程序能够调用cons_putchar函数。这里存在两个问题,一个问题是函数没法接收存在寄存器上的字符编码,再一个问题是我们不知道cons_putchar函数的地址。所以我们先写一个函数_asm_cons_putchar,将寄存器的值推入栈中,再在这个函数中调用cons_putchar函数。

调用结构图如下:

在这里插入图片描述

在bootpack.map文件中我们能够查找到cons_putchar函数的地址,将它填入到代码中。

bootpack.map文件:

在这里插入图片描述

我们将地址填入应用程序中,需要注意的是,当应用程序通过API执行CALL指令实现函数调用时,需要加上段号。这里操作系统的段为“2*8”,使用far-CALL,同时指定段和偏移量。

hlt.nas文件:

[BITS 32]
		MOV		AL,'A'       ;这句就是API
		CALL    2*8:0xbe3    ;还有这句
fin:
		HLT
		JMP		fin

cons_putchar函数的地址保存在内存中,这里保存在BOOTINFO之前的0x0fec。

console.c节选:

void console_task(struct SHEET *sheet, unsigned int memtotal)
{
   
	(略)
	cons.sht = sheet;
	cons.cur_x =  8;
	cons.cur_y = 28;
	cons.cur_c = -1;
	*((int *) 0x0fec) = (int) <
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值