LINUX下系统调用执行过程

本文详细阐述了系统调用的工作原理,包括通过软中断0x80进入内核空间的过程,以及如何通过系统调用号分派到相应服务例程。此外还介绍了参数传递的方式及在堆栈中的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      通过软件中断0x80,系统会跳转到一个预设的内核空间地址,它指向了系统调用处理程序(不要和系统调用服务例程相混淆),即在arch/i386/kernel/entry.S文件中使用汇编语言编写的system_call函数。很显然,所有的系统调用都会同一跳转到这个地址进而执行system_call函数,那么system_call函数又该如何派发它们到各自的服务例程呢? 

  软中断指令int 0x80执行时,系统调用号会被放进eax寄存器,同时,sys_call_table每一项占用4个字节。这样,system_call函数可以读取eax寄存器获得当前系统调用的系统调用号,将其乘以4天生偏移地址,然后以sys_call_table为基址,基址加上偏移地址所指向的内容即是应该执行的系统调用服务例程的地址。 

  另外,除了传递系统调用号到eax寄存器,假如需要,还会传递一些参数到内核,比如write系统调用的服务例程原型为: 调用write系统调用时就需要传递文件描述符fd、要写进的内容buf以及写进字节数count等几个内容到内核。ebx、ecx、edx、esi以及edi寄存器可以用于传递这些额外的参数。 

  正如之前所述,系统调用服务例程定义中的asmlinkage标记表示,编译器仅从堆栈中获取该函数的参数,而不需要从寄存器中获得任何参数。进进system_call函数前,用户应用将参数存放到对应寄存器中,system_call函数执行时会首先将这些寄存器压进堆栈。 

  对于系统调用服务例程,可以直接从system_call函数压进的堆栈中获得参数,对参数的修改也可以一直在堆栈中进行。在system_call函数退出后,用户应用可以直接从寄存器中获得被修改过的参数。 

 

   系统调用通过软中断0x80陷进内核,跳转到系统调用处理程序system_call函数,并执行相应的服务例程,但由于是代表用户进程,所以这个执行过程并不属于中断上下文,而是处于进程上下文。  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值