9

受这个问题的启发

如何强制 GDB 反汇编?

和这个有关

什么是 INT 21 小时?

在 linux 下实际的系统调用是如何发生的?执行调用时会发生什么,直到调用实际的内核例程?

4

4 回答 4

8

假设我们谈论的是 x86:

  1. 系统调用的ID存入 EAX 寄存器
  2. 系统调用所需的任何参数都存放在系统调用指定的位置。例如,一些系统调用期望它们的参数驻留在 EBX 寄存器中。其他人可能希望他们的论点位于堆栈的顶部。
  3. INT 0x80调用中断。
  4. Linux 内核为 EAX 寄存器中的 ID 标识的系统调用提供服务,将任何结果存放在预定位置。
  5. 调用代码使用任何结果。

我可能对此有点生疏,已经有几年了......

于 2009-08-07T17:05:36.987 回答
7

给出的答案是正确的,但我想补充一点,还有更多机制可以进入内核模式。每个最近的内核都在每个进程的地址空间中映射“vsyscall”页面。它只包含最有效的系统调用陷阱方法。

例如,在常规 32 位系统上,它可能包含:

 
0xffffe000: int $0x80
0xffffe002: ret

但是在我的 64 位系统上,我可以使用 syscall/sysenter 指令获得更有效的方法


0xffffe000: push   %ecx
0xffffe001: push   %edx
0xffffe002: push   %ebp
0xffffe003:     mov    %esp,%ebp
0xffffe005:     sysenter 
0xffffe007: nop    
0xffffe008: nop    
0xffffe009: nop    
0xffffe00a: nop    
0xffffe00b: nop    
0xffffe00c: nop    
0xffffe00d: nop    
0xffffe00e:     jmp    0xffffe003
0xffffe010: pop    %ebp
0xffffe011: pop    %edx
0xffffe012: pop    %ecx
0xffffe013: ret    

此 vsyscall 页面还映射了一些无需上下文切换即可完成的系统调用。我知道某些gettimeofdaytimegetcpu映射在那里,但我想getpid也可以在那里。

于 2009-08-09T23:27:37.873 回答
4

这已经
在 Linux 中的系统调用是如何实现的?
由于不同的“系统调用”术语用法,可能与此问题不匹配。

于 2009-08-07T17:20:10.297 回答
3

基本上,它非常简单:内存中的某处有一个表,其中存储了每个系统调用号和相应处理程序的地址(参见http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32 .S代表 x86 版本)

INT 0x80 中断处理程序然后只是从寄存器中取出参数,将它们放在(内核)堆栈上,并调用适当的系统调用处理程序。

于 2009-08-07T17:12:28.067 回答