1.问题描述

在前面的文章中,已经了解了Linux内核源代码的目录结构,并在Oracle VM VirtualBox的Linux环境中构造一个简单的操作系统MenuOS,本文将学习系统调用的相关理论知识,使用库函数API和C代码中嵌入汇编代码两种方式使用getpid()系统调用。

2.解决过程

2.1 系统调用



上图所示,Linux操作系统的体系架构在宏观上分为用户态和内核态。

用户态:在用户态下,代码能够掌握的范围会受到一定限制。

内核态:在内核态下,代码可以执行特权指令,访问任意的物理内存。

系统调用:由操作系统实现提供的所有系统调用所构成的集合即程序接口或应用编程接口(Application Programming Interface,API),是应用程序同系统之间的接口。系统调用也是一种中断,中断处理是从用户态进入内核态的主要方式。

系统调用3层机制:

第一步,系统调用的库函数就是读者使用的操作系统提供的API,调用软中断向内核发出中断请求;

第二步,CPU切换到内核态并开始执行一个system_call和系统调用内核函数,具体通过int $0x80触发系统调用的执行;

第三步,进入内核,通过系统调用号将API函数和系统调用内核函数关联起来进行调用。

参数传递:系统调用中,用户态切换到内核态,两种执行模式使用不同堆栈,参数传递通过特殊寄存器来进行。在x86-32中,EAX用于传递系统调用号,其余参数按顺序赋值给EBX,ECX,EDX,ESI,EDI和EBP,参数个数一般不超过6个。如果超过6个就把一个寄存器作为指针指向内存用于存储参数。

下面小节将通过直接调用库函数和使用汇编语言进行系统调用。

2.2 使用库函数API进行系统调用

根据/usr/include/asm/unistd_32.h,选取调用号为20的库函数getpid(),输入以下代码:

#include<unistd.h>
#include<stdio.h>
int main()
{
int pid;
pid=getpid();
printf("pid=%d\n",pid); return 0;
}

gcc编译后,显示获取的pid如下图所示:

2.3 C代码中嵌入汇编代码进行系统调用

通过objdump -d反汇编查询编译过程,运行以下代码:

#include<unistd.h>
#include<stdio.h>
int main()
{
int pid;
__asm__ __volatile__(
"mov $0,%%ebx\n\t"
"mov $0x14,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax, %0\n\t"
:"=m" (pid)
);
pid=getpid();
printf("pid=%d\n",pid); return 0;
}

显示结果如下:



分析__asm__ __volatile__函数中汇编语言的参数传递方式,首先将EBX置空,然后将系统调用号20传入EAX寄存器,在16进制中,0x14表示十进制的2,然后运行int $0x80指令,产生中断向量为128的编译异常,进入内核后开始执行中断向量128对应的中断服务程序system_call,根据EAX寄存器存储的系统调用号调用getpid(),将返回值传回用户态参数pid。

3.总结

本文主要学习系统调用的相关理论知识,了解了系统调用主要是执行用户态到内核态API的调用。其中有关系统调用引起的中断处理在操作系统的课程学习中有所涉略,本次更加深入了解了系统调用的3层机制,教材中使用库函数API和C代码中嵌入汇编代码两种方式分别对time()和rename()函数进行系统调用,本文根据系统调用号对应表选择getpid()来模拟两种方式的调用,也是在之前学习汇编和反汇编的方法后的一次实践编程,更好地掌握系统调用的精髓知识。

最新文章

  1. js如何求一组数中的极值
  2. 关于SharePoint 2013的工作流(二)
  3. 关于application/x-www-form-urlencoded等字符编码的解释说明
  4. Freemarker 内置函数 数字、字符串、日期格式化用法介绍
  5. 【BZOJ-3437】小P的牧场 DP + 斜率优化
  6. BS模式的模型结构详解
  7. *[topcoder]JumpFurther
  8. sql restore mode
  9. 使用window.postMessage实现跨域通信
  10. 安卓Launcher之获取手机安装的应用列表,安卓launcher
  11. hdu2066一个人的旅行
  12. Java中4种类型的内部类 .
  13. iconfont字体图标的使用方法--超简单!
  14. go延时队列
  15. ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案 try.dot.net 的正确使用姿势 .Net NPOI 根据excel模板导出excel、直接生成excel .Net NPOI 上传excel文件、提交后台获取excel里的数据
  16. 深入理解uwsgi和gunicorn网络模型
  17. JavaWeb -cookie&amp;session&amp;application
  18. Http 请求 GET和POST的区别
  19. BASH 的调试技巧
  20. AspectJ AOP介绍

热门文章

  1. [vijos1574]摇钱树&lt;dp+贪心&gt;
  2. Salesforce LWC学习(十五) Async 以及 Picklist 公用方法的实现
  3. 解决MySQL workbench的resultgird不出现的问题
  4. Shell:Day03笔记
  5. [SCF+wetest+jmeter]简单云性能压测工具使用方案
  6. kafka的基本体系结构
  7. golang trace 分析 简例
  8. AJ学IOS(46)之网易彩票幸运大转盘
  9. threejs使用各种坑实验过程
  10. PDM添加唯一性约束