进程—异常控制流之陷阱篇

本文详细介绍了进程中的异常控制流,特别是陷阱和系统调用的概念。陷阱作为有意触发的异常,主要用于实现用户程序与内核之间的系统调用接口。系统调用如read、fork等服务在内核模式下执行,通过int n指令产生陷阱,进入内核。参数通过寄存器传递,Linux的sys_call_table存储了所有系统调用的函数指针。在IA32系统上,int 0x80常用于系统调用,执行时会切换到内核栈并保存上下文,然后根据系统调用号找到对应的服务程序执行。

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

一、Exceptions(异常) and System Call(系统调用)

1.1 陷阱


p54 Protection Rings

陷阱是有意为之的异常,是处理器执行程序的一条指令的结果。陷阱最重要的用途是提供用户程序和内核之间一个像普通过程调用似的接口,名曰:系统调用。用户程序经常需要向内核请求服务,比如读一个文件(read) 、创建一个新的进程(fork) 、加载一个新的程序(execv),或者终止当前进程(exit) 。为了允许对这些内核服务的受控的访问,处理器提供了一条特殊的 “syscall n” 指令,当用户程序想要请求服务n时,可以执行这条指令。执行syscall 指令会导致一个到异常处理程序的陷阱,这个处理程序对参数解码,并调用适当的内核程序。

1.1.1 System Call N


p60 System Call N

系统调用运行在内核模式中,内核模式允许执行系统调用函数的指令,并访问定义在内核中的栈。

Examples of popular system calls:


p62 Examples of popular system calls

Linux provides hundreds of system calls.
Source: /usr/include/sys/syscall.h.

1.1.2 实现

1.在IA32 系统上,系统调用是通过一条称为int n1 的陷阱指令来提供的,其中n可能是IA32 异常表 中256 个条目中任何一个的索引。在历史上,系统调用是通过异常128 (Ox80) 提供的。

2.所有的传到Linux系统调用服务程序的参数都是通过寄存器传递的。按照惯例,寄存器%eax包含系统调用号,寄存器%ebx 、%ecx 、%edx 、%esi 、%edi和%ebp 包含最多六个任意的参数。栈指针%esp不能使用,因为当进入内核模式时,内核会覆盖它。

3.C程序用syscall函数可以直接调用任何存在于系统调用表中的系统调用。然而,实际中几乎没必要这么做。对于大多数系统调用,标准C库提供了一组方便的包装函数。这些包装函数将参数打包到一起,以适当的系统调用号陷入内核,然后将系统调用的返回状态传递回调用程序。我们将系统调用和与它们相关联的包装函数称为系统级函数

4.内核记录了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值