在 32 位 x86 架构中,int 0x80用作系统调用指令。内核已经为处理器准备了一个软件中断处理程序表。常规用户空间代码不能直接访问此表,但使用int用户空间代码可以触发该表指向的例程之一的指令。int 0x80只是告诉处理器切换到内核模式并跳转到地址在该表的插槽#128 中的例程。该例程是 Linux 的 32 位 x86 架构的系统调用接口:它检查指定的参数,识别哪个进程进行了调用,然后跳转到适当的子例程。
在 x86 架构的 64 位版本中,有一条专用syscall指令用于相同目的。实际上现在 32 位 x86 架构也有,但是或者在 Linus Torvalds 设计 32 位 Linux 系统调用约定时它还不存在,或者该指令在某些处理器型号中存在硬件错误,所以它没有习惯了。但是由于所有 64 位 x86 处理器都有该syscall指令并且它确实有效,因此使用它。
mov [register]
和类似的不是系统调用,而是汇编指令。系统调用基本上是一个用户空间程序调用内核中的特定子例程,使用处理器内置并由内核设置的机制,允许被调用的子例程具有比常规用户空间更高的特权级别程序代码。
汇编指令基本上是机器代码实际字节的人性化表示。机器代码既不解释也不编译,而是在处理器内部使用处理器微码实现,或者直接在硬件级别使用大量逻辑门实现。
汇编语言中的单个系统调用调用通常是多行代码。首先,系统调用的参数被加载到适当的处理器寄存器和/或堆栈中,然后使用类似
int 0x80
or的特殊指令syscall
来实际进行系统调用。在 32 位 x86 架构中,
int 0x80
用作系统调用指令。内核已经为处理器准备了一个软件中断处理程序表。常规用户空间代码不能直接访问此表,但使用int
用户空间代码可以触发该表指向的例程之一的指令。int 0x80
只是告诉处理器切换到内核模式并跳转到地址在该表的插槽#128 中的例程。该例程是 Linux 的 32 位 x86 架构的系统调用接口:它检查指定的参数,识别哪个进程进行了调用,然后跳转到适当的子例程。在 x86 架构的 64 位版本中,有一条专用
syscall
指令用于相同目的。实际上现在 32 位 x86 架构也有,但是或者在 Linus Torvalds 设计 32 位 Linux 系统调用约定时它还不存在,或者该指令在某些处理器型号中存在硬件错误,所以它没有习惯了。但是由于所有 64 位 x86 处理器都有该syscall
指令并且它确实有效,因此使用它。