30天自制操作系统------字符串显示API

来源:互联网 发布:电磁辐射检测软件 编辑:程序博客网 时间:2024/04/30 23:10


操作系统一般都会有一些系统功能可以供应用程序来使用,最基础的就是显示字符、字符串的API了。

 

一、API的编写

目前我们的应用程序都很简单,都是使用简单的汇编进行编写的。

而我们显示字符的函数cons_putchar是用C语言编写的,即使应用程序想要调用cons_putchar函数,首先需要传参,但是汇编语言是无法使用寄存器来给C函数传参的,所以我们需要在调用cons_putchar函数之前将其所需要的参数压入栈,这部分需要使用汇编语言来完成。将参数压栈并且调用函数cons_putchar的汇编代码就可以作为一个简单的API

 

二、API的调用

1、使用函数调用实现API调用

应用程序想要调用API,在汇编指令中可以使用CALL指令来实现API的调用,但是在使用CALL指令时需要注意CALL指令默认是调用当前段内的函数,但是应用程序和操作系统所处的段是不同的,所以在使用CALL指令时需要指明具体是哪个段。

应用程序所在的段是1003*8”,而操作系统所在的段是“2*8”,所以应用程序在调用对应的函数时应该使用FAR-CALL,即同时改变寄存器EIP以及CS的值。

使用FAR-CALL调用相关函数,那么函数返回的指令也要做出相应的改变,原本使用汇编语言编写的API函数的返回语句是RET,这在汇编语言中执行的动作就是POP EIP,而使用FAR-CALL时改变的不仅是EIP的值,而且还改变了CS的值,所以需要使用RETF指令来恢复这两个寄存器的值。

  

2、使用中断机制调用API

使用FAR-CALL指令来调用API需要知道API函数的在内存中存放的地址,而API函数的地址是可以根据操作系统的编写不断变化的,这样就使得使用这个API非常不方便。

在操作系统中,IDT(中断记录表)可以记录中断函数的存储位置,我们可以将API函数所在的位置保存在IDT中,这样我们在调用API的时候,就可以通过查找IDT来获得API函数的位置,而且调用时也不必再使用FAR-CALL指令,直接使用INT指令触发相应的中断即可。

IRT只有0~15,而CPU用于通知异常状态的中断最多只有32种,而IDT中最多可以设置256个函数,因此还剩下很多没有使用的项,所以我们使用一个也不会有什么问题。

使用INT指令来调用相应的函数与使用FAR-CALL指令还是有差别的。

INT指令在执行被调用函数之前,按顺序将EFLAGCSEIP寄存器的值压栈,所以API函数返回时,使用RETF是会发生错误的,应该使用IRETD指令代替。

 

CALLFAR-CALLINT指令的区别:

指令

动作

CALL

PUSH EIP

然后执行被调用者的动作

                  RET

   POP EIP

CALL FAR

PUSH CS

PUSH EIP

然后执行被调用者的动作

RETF

POP EIP

POP CS

INT

PUSH EFLAG

PUSH CS

PUSH EIP

然后执行被调用者的动作

IRETD

POP EIP

POP CS

POP EFLAG

 

三、注意事项

   因为我们的应用程序以及API都是使用汇编进行编写的,所以寄存器的分配工作都是我们需要考虑的事情,在汇编程序中使用函数调用,中断机制等时,我们并不能保证子程序执行时不会改变父程序中将要使用到的寄存器的值,为了保证程序的正确执行,在执行每个子程序之前,可以先将子程序中所要用到的寄存器中的值压栈,在程序返回之前再使用栈中的数据恢复寄存器的值,这样就可以避免因寄存器分配引起的程序错误。

原创粉丝点击