在阅读OSTEP书时,我有一个问题。
为了指定确切的系统调用,通常会为每个系统调用分配一个系统调用号。因此,用户代码负责将所需的系统调用号放入寄存器或堆栈上的指定位置;操作系统在处理陷阱处理程序内的系统调用时,会检查该数字,确保其有效,如果有效,则执行相应的代码。这种间接级别可以作为一种保护形式;用户代码无法指定要跳转到的确切地址,而是必须通过号码请求特定服务。
我试图更好地理解系统调用号在系统调用和陷阱处理的上下文中如何工作。目前我的理解是这样的:
我的理解准确吗?有人可以澄清或提供更多详细信息,特别是关于 C 库的作用和验证步骤吗?
- 系统调用号就像陷阱表中的键或索引一样使用,允许CPU跳转到正确的陷阱处理程序。
不。陷阱编号是一回事,系统调用编号是另一回事。
CPU 通常支持单个无参数
TRAP
指令,在这种情况下,只有一个陷阱处理程序,因此没有陷阱号和陷阱表,或者它支持 TRAP N
指令,其中 N
是陷阱编号。
如果CPU支持多个陷阱处理程序,那么就会有一个“陷阱表”,它将陷阱号映射到陷阱处理程序的地址。操作系统将定义一个或多个这样的陷阱处理程序。
假设我们有一个支持多个陷阱处理程序的假设 CPU,以及一个使用
TRAP 42
进行系统调用的操作系统。
系统调用号是您在调用该陷阱之前必须设置的内容。例如:
LOAD R1, system_call_number
TRAP 42
因此,在
TRAP 42
的处理程序中,操作系统将使用 R1
的值在 另一个 表(称为“系统调用”表)中查找系统函数的地址,然后跳转到它。
- 在陷阱处理程序内,操作系统验证系统调用号。
呃,当然。 如果系统调用号与实际有效的系统函数不对应,操作系统可能会对您的进程做坏事。
- C 库的系统调用 API 在调用陷阱之前将系统调用号存储在寄存器或堆栈中。
我不知道你所说的“C 库的系统调用 API”是什么意思。无论如何,任何有兴趣调用系统调用的人都必须“在调用陷阱之前将系统调用号存储在某处”。操作系统定义了它的存储位置。它通常在寄存器中。
还要注意,术语“TRAP”可能来自特定的CPU架构,但它不是通用术语,并且没有标准术语。例如,在Intel x86世界中,这被称为“中断”,调用它的对应指令是“INT”。