受这个问题的启发
和这个有关
在 linux 下实际的系统调用是如何发生的?执行调用时会发生什么,直到调用实际的内核例程?
给出的答案是正确的,但我想补充一点,还有更多机制可以进入内核模式。每个最近的内核都在每个进程的地址空间中映射“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 页面还映射了一些无需上下文切换即可完成的系统调用。我知道某些gettimeofday,time和getcpu映射在那里,但我想getpid也可以在那里。
这已经
在 Linux 中的系统调用是如何实现的?
由于不同的“系统调用”术语用法,可能与此问题不匹配。
基本上,它非常简单:内存中的某处有一个表,其中存储了每个系统调用号和相应处理程序的地址(参见http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/syscall_table_32 .S代表 x86 版本)
INT 0x80 中断处理程序然后只是从寄存器中取出参数,将它们放在(内核)堆栈上,并调用适当的系统调用处理程序。