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