浅谈C语言函数调用与系统调用
1. 函数调用和系统调用概述
1.1 定性的去区分函数调用和系统调用
很多初学C语言的同学,亦或者开发中很少接触系统底层的同学可能会认为函数调用以及系统调用是一回事。因为在应用程序,两者都被抽象成接口去给应用程序调用。其实函数调用和系统调用还是有区别,我们通过下图先有个全局的了解!
从图1-1 我们可以知道应用程序访问内核,主要通过两种方式:中断和系统调用接口。
其一,中断是置于程序流程之外的,所以这种方式并不是我们访问内核的普遍方式,更多的是因为程序异常而引起的中断;
其二,就是系统调用接口,例如使用 open、read 以及 write 去操作文件数据(相当于去访问硬盘)。
而函数调用是无法直接访问内核的,函数调用需要访问内核,也只能通过系统调用的方式。
所以,我们可以通过这种方式定性地去区分函数调用和系统调用: 接口直接访问内核的属于系统调用,其他则为函数调用。
1.2 为什么要封装好系统调用
我们知道,32位 linux系统为了保证程序独立性,给每一个进程分配独立的4G地址空间(虚拟内存空间),但是4G地址空间又被划分为两个空间:用户空间以及内核空间,如下图:
用户空间,存储的是一些进程常见的数据,例如代码、变量数据、堆区和栈区等,需要注意的是内核空间,虽然说系统给每一个进程都分配1G大小的内核空间,但是实际上,内核空间是操作系统中进程公用的。公用就会带来一个现实性的问题,就比如我们可以在自己的房间干任何事情(用户空间),去不能在公共场合(内核空间)为所欲为,活动在公共场合(内核空间),我们的行为会受到限制,对于操作系统也一样道理,内核空间属于进程公用,进程去访问内核必须保证不会给其他进程造成影响。
如何去保证进程操作系统中公用的内核空间不会出现非法操作,打个比方说:如何保证银行内部数据不被非法操作,银行是提供一个ATM给你,你只能选择上面的接口操作。操作系统也“学习”了这样的模式,封装接口,保证数据操作正确性!
不仅仅应用程序无法直接访问内核空间,只能通过系统调用访问内核空间,而且内核对用户空间的数据的不信任,对于通过系统调用的传递过来的数据也会做相应的检查,确保内核安全,确保内核安全是必须的,内核属于系统的软件核心,内核崩溃会导致整个软件系统的崩溃。为了保证应用程序传递的数据合法性以及内核数据的绝密性,通常会使用copy_from_user去检验和拷贝传递过来的数据,使用copy_to_user()检验和拷贝数据给应用程序。
2.函数调用
2.1 什么叫做函数调用
int add(int a, int b){return(a + b);
}int main(){int sum;sum = add(1 + 2);return 0;
}
如上是一个最简单的函数调用过程,了解什么叫函数调用,我们可以通过了解什么是函数?
函数(function)是完成特定任务的独立程序代码单元。
----《C Primer Plus》
再来了解为啥需要使用函数?
首先,使用函数可以省去编写重复代码的苦差。如果程序多次完成某一项。如果程序需要多次完成某项任务,那么只需编写一个适合的函数,就可以在需要时使用这个函数,或者在不同的程序中使用该函数,就像许多程序使用putchar() 一样。
其次,即使程序只完成某项任务一次,也值得使用函数。因为函数使程序更加模块化,从而提高了程序代码的可读性,更方便后期修改、完善。
----《C Primer Plus》
函数调用是很好理解的,提高代码重用性以及模块性,调用相对应函数,得到某种结果。
2.1 函数调用的过程
函数调用会发生函数压栈以及出栈过程,具体可以参考如下博文和视频(博主对汇编不熟悉,所以就不具体分析了,以免误人子弟!)。
浅析函数的调用过程
汇编中的函数调用中栈的工作过程
3.系统调用
3.1 什么叫做系统调用
为了和用户空间上运行的进程进行交互,内核提供了一组接口。透过该接口,应用程序可以访问硬件设备和其他操作系统资源。这组接口在应用程序和内核之间扮演了使者的角色,应用程序发送各种请求,而内核负责满足这些请求(或者让应用程序暂时搁置)
----《Linux内核设计与实现》
3.2 系统调用的过程
系统调用和函数调用在应用程使用几乎没有差别,但是内部实现过程是完全不同的,函数调用是通过函数入口地址直接跳转函数服务程序,而系统调用并非直接跳转系统调用服务程序,因为内核地址对于应用程序是不可用的,需要通过中断的方式进入内核态,再通过一系列的操作找到对应的服务程序。
我们可以通过下图有一个了解:
希望更详细的了解系统调用过程可以看看下面这篇博文:
ioctl系统调用过程(深入Linux(ARM)内核源码)
浅谈C语言函数调用与系统调用相关推荐
- c语言函数调用参数调用的太少,浅谈C语言函数调用参数压栈的相关问题
参数入栈的顺序 以前在面试中被人问到这样的问题,函数调用的时候,参数入栈的顺序是从左向右,还是从右向左.参数的入栈顺序主要看调用方式,一般来说,__cdecl 和__stdcall 都是参数从右到左入 ...
- c语言函数参数压栈,函数调用压栈 浅谈C语言函数调用参数压栈的相关问题
想了解浅谈C语言函数调用参数压栈的相关问题的相关内容吗,在本文为您仔细讲解函数调用压栈的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:函数调用压栈,下面大家一起来学习吧. 参数入栈的顺序 ...
- c语言 去掉双引号_技术分享|浅谈C语言陷阱和缺陷
良好的软件架构.清晰的代码结构.掌握硬件.深入理解C语言是防错的要点,人的思维和经验积累对软件可靠性有很大影响.C语言诡异且有种种陷阱和缺陷,需要程序员多年历练才能达到较为完善的地步.软件的质量是由程 ...
- 浅谈go语言交叉编译
浅谈go语言交叉编译 基础 cgo cgo设置编译和链接参数 静态库和动态库 静态库 动态库 静态编译 cgo的内部连接和外部连接 internal linking external linking ...
- 分三种情况C语言编程,浅谈C语言教学的现状及几点建议.doc
浅谈C语言教学的现状及几点建议 浅谈C语言教学的现状及几点建议 摘 要 针对C语言教学中存在的问题提出建议,以期对C语言教学有一定帮助. 关键词 C语言:课程设置:创新能力 中图分类号:G642 文献 ...
- 浅谈C语言内存(栈)
浅谈C语言内存 文章目录 浅谈C语言内存 内存分配 栈 斐波纳契数列 内存分配 在C语言中内存分别分为栈区(stack).堆区(heap).未初始化全局数据区.已初始化全局数据区.静态常量区(stat ...
- 基于c语言的递归算法分析论文,浅谈C语言递归算法.docx
浅谈C语言递归算法 浅析C语言递归算法王浏江盐城师范学院 信息工程学院 计算机161班 摘要:递归算法,结构清晰,代码简练,函数调用灵活方便,比较容易理解和阅读.因此,递归算法一般用于多个相似小问题组 ...
- c程序语言的常量变量和标识符,浅谈C语言中的常量与变量.pdf
课程教育研究 CourseEducationResearch 2014年4月 上旬刊 教学.信息 浅谈C语言中的常量与变量 刘 星 (青 岛工学院商学院 山东 青岛 266300) [摘要]在任何一种 ...
- c语言结构共用体的作用,浅谈C语言共用体和与结构体的区别
共用体与结构体的区别 共用体: 使用union 关键字 共用体内存长度是内部最长的数据类型的长度. 共用体的地址和内部各成员变量的地址都是同一个地址 结构体大小: 结构体内部的成员,大小等于最后一个成 ...
- c语言乐学编程作业答案,信息乐学|浅谈C语言
原标题:信息乐学|浅谈C语言 一大波C语言的干货正在靠近 刚刚成为大学生的小萌新们,经过两个多月的学习,你们对大学的多彩生活是否还满意?全新的学习方式你们是否还适应?然而,新鲜劲还没过,第一件让你们头 ...
最新文章
- Linux 批量kill死进程
- Jsp实现停车场管理系统
- 生日快乐html_生日快乐,我的祖国
- vs 服务容器中已存在服务_容器中某Go服务GC停顿经常超过100ms排查
- 校验html输入值为电话号码,js验证输入是否为手机号码或电话号码示例
- php网页登录制作,thinkphp5 系统登录的实现
- 外表加载oracle,opengauss外部表插件——oracle_fdw
- 判断这5个数值是否连续相邻
- 学生宿舍管理系统java课设_java编写的学生宿舍管理系统
- Android代码中设置横屏
- mysql跨库oracle查询,Oracle跨数据库查询(databaselink方式)
- graphpad做单因素方差分析_GraphPad中国官网 - Prism 8 统计指南 - 单因素方差分析
- R 加权最小二乘 代码_如何用EXCEL的规划求解功能优化投资组合的阿尔法值(最小二乘估计法)?...
- android p屏幕使用时间,MIUI迎来第414周更新,新增屏幕使用时间,小米6获Android P更新!...
- 电信smgp3.0短信发送问题
- 如何让青少年远离“网络成瘾”?
- 牛客网SQL 进阶篇刷题
- 微信好友列表服务器,微信小游戏如何实现邀请好友列表
- mid360 SLAM 建图实现
- Android小项目——新闻APP