汇编代码调用系统调用的工作过程

钟晶晶 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

工作过程

以41号进程dup为例,说明在应用程序如何使用Linux的系统调用。dup()复制一个打开的文件描述符,并返回一个新描述符,二者都指向同一个打开的文件句柄。系统会保证新描述符一定是编号低最低的未使用文件描述符。
使用库函数API调用dup()的程序:

使用C语言嵌入汇编代码来实现调用dup():

第一条汇编语句将立即数复制到寄存器edi,用作dup()的参数,表示要复制的描述符;
第二条汇编语句将立即数41复制到寄存器eax,41是dup()在内核中的系统调用号;
第三条汇编语句执行中断指令int,从用户态切换到内核态,发起系统调用;
第四条汇编语句将寄存器eax中保存的系统调用返回值复制fd,表示复制的新描述符。

可以看出上面两个小程序的功能是等价的,复制得到的新描述符值都是3,因为文件描述符0、1和2分别用作标准输入,标准输出和标准输出。

系统调用的三层皮:

API、中断向量对应的system_call、中断服务程序sys_xyz

当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数,在Linux中是通过执行int $0x80来执行系统调用的,这条汇编指令产生向量为128的编程异常。(Intel Pentium II中引入了sysenter指令(快速系统调用),2.6已经支持)内核实现了很多不同的系统调用,进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数,使用eax寄存器(系统调用号将xyz()和sys_xyz()关联起来了)

系统调用的参数传递方法

system_call是linux中所有系统调用的入口点,每个系统调用至少有一个参数,即由eax传递的系统调用号
一个应用程序调用fork()封装例程,那么在执行int $0x80之前就把eax寄存器的值置为2(即__NR_fork)
这个寄存器的设置是libc库中的封装例程进行的,因此用户一般不关心系统调用号
进入sys_call之后,立即将eax的值压入内核堆栈

寄存器传递参数具有如下限制:
1)每个参数的长度不能超过寄存器的长度,即32位
2)在系统调用号(eax)之外,参数的个数不能超过6个(ebx, ecx,edx,esi,edi,ebp)
超过6个怎么办?

如果超过6个,就把某一个寄存器作为一个指针,指向一块内存,进入到内核态之后可以访问到所有的地址空间,通过内存来传递参数

时间: 2024-10-10 12:05:06

汇编代码调用系统调用的工作过程的相关文章

通过库函数API和C代码中嵌入汇编代码剖析系统调用的工作机制

作者:吴乐 山东师范大学<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 本次实验的主要内容就是分别采用API和gcc嵌入汇编的方式调用system_call.系统调用其实就是操作系统提供的服务.我们平时编写的程序,如果仅仅是数值计算,那么所有的过程都是在用户态完成的,但是我们想将变量打印在屏幕上,就必须调用printf,而printf这个函数内部就使用了write这个系统调用.操作系统之所以以system ca

使用汇编代码调用系统调用

“casualet + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”, Linux系统中提供了很多的系统调用, 这是用户程序进入0特权级和硬件交互的接口. 我们用c语言进行编程的时候, 使用的很多库函数就是对系统调用的一种封装. 所有的系统调用都是通过int 0x80以一种软中断的方式来实现的, 为了区别不同的系统调用, 有一个系统调用的号, 可以通过这个网址进行查询:http

分析汇编代码理解计算机如何工作

周玉勇 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 把C代码反汇编成汇编代码,再来分析计算机如何工作 下面是C代码 C代码编译成汇编的代码 简化的汇编代码 1 g: 2 pushl %ebp 3 movl %esp, %ebp 4 movl 8(%ebp), %eax 5 addl $6, %eax 6 popl %ebp 7 ret 8 f: 9 pushl %ebp 10 mov

作业四:系统调用的工作机制

系统调用的工作机制 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/syscall_32.tbl 一.前情提要 系统调用 操作系统为用户态进程与硬件设备进行交互提供了一组接口 API 应用编程接口,是一个函数定义. 系统调用通过软中断向内核发出明确的请求.(eg:sysenter) 操作系统提供API和系统调用的关系 Libc库定义的

用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

姓名:王晨光 学号:20133232 王晨光 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 本周的实验相比较前面3次实验较为容易理解,这次实验的浅析了系统调用的工作过程,通过用库函数API和C代码嵌入汇编代码两种方式使用同一个系统调用. 我这次实验选择了20号系统调用getpid来获取进程ID.首先我先在网上查阅了getpid函数是用来获取目前进程的ID,许多程序利用取到的此值

lab4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

李俊锋 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验原理 1.1系统调用的意义 (1)把用户从底层的硬件编程中解放出来 (2)极大的提高了系统的安全性 (3)使用户程序具有可移植性 1.2系统调用过程 (1)当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数. (2)在Linux中是通过执行int $0x80来执行系统调用的,这条汇编指令产生向量

实验--使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用(杨光)

使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 攥写人:杨光  学号:20135233 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验要求: 选择一个系统调用(13号系统调用time除外),系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/sys

理解计算机的工作方式——通过汇编一个简单的C程序并分析汇编代码

Author: 翁超平 Notice:原创作品转载请注明出处 See also:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000  本文通过汇编一个简单的C程序,并分析汇编代码,来理解计算机是如何工作的.整个过程都在实验楼上完成,感兴趣的读者可以通过上面给出的课程链接自行动手学习.以下是实验过程和结果. 一.操作步骤 1.首先在通过vim程序建立main.c文件.代码如下: 图1 2.使用如下命令将main.c编

系统调用的API以及汇编代码实现

作者:严哲璟 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 系统调用过程为getpid()即返回当前进程的ID 使用汇编代码 用库函数实现 参数传递方式:eax传递系统调用号,库函数的参数按照从左至右传递到ebx,ecx,edx,esi,edi的顺序存储,返回值为eax.当参数个数大于6个的时候,需要制定一个寄存器来存放一段内存地址的起始地址,将所有的参数都放入这段地址中. 系统调