在i386和x86-64上UNIX和Linux系统调用的调用约定是什么

系统调用是应用程序和Linux内核之间的基本接口。当Unix / Linux程序执行文件I / O,网络数据传输或调用某个与低级指令直接或间接交互的进程时,就会涉及系统调用。进行这些调用通常涉及使用名为glibc的库,该库包含函数。

例子

以下是一些常用的系统调用及其用途的列表。

序号系统调用目的
1chmod更改文件的权限
2chdir更改工作目录
3叉子创建一个子进程
4取消连结删除名称以及它所引用的文件

系统程序员编写的程序不会直接进行系统调用,而只会指定要使用的系统调用。这涉及使用依赖于内核的调用约定或内核所在系统的硬件体系结构。因此,不同的体系结构具有不同的调用约定。

调用约定是实现级别的设计,用于子例程如何从其调用者接收参数以及如何返回结果。各种实现方式的差异包括放置参数,返回值,返回地址和作用域链接(寄存器,堆栈或内存等)的位置,以及如何在调用方和调用方之间划分准备函数调用和随后还原环境的任务。被呼叫者。

呼叫约定变化

以下是一些场景列表,描述了不同架构之间的调用约定如何变化

  • 哪个注册的被调用函数必须保留给调用者。

  • 在函数调用后如何设置和清理任务在调用者和被调用者之间如何划分。

  • 返回值如何从被调用方传递回调用方-在堆栈上,在寄存器中还是在堆内等。

  • 放置参数,返回值和返回地址的位置

  • 形式参数的实际参数传递的顺序。

比较x86-32和x86-64位

单个CPU体系结构始终具有不止一种可能的调用约定,但业界已同意采用不同生产者的跨体系结构的某种通用方法。32位体系结构具有32个寄存器,而x64将x86的8个通用寄存器扩展为64位。因此,调用约定的实现有所不同。下面是这两种架构之间主要调用约定的比较。

x-86 32位x-86 64位
用于系统调用的寄存器是-%ebx,%ecx,%edx,%esi,%edi,%ebp用于系统调用的寄存器是-%rdi,%rsi,%rdx,%r10,%r8和%r9
使用PUSH机制在堆栈上传递参数。如果有六个以上的参数,%ebx必须包含参数列表存储的内存位置系统调用仅限于六个参数。如果有6个以上INTEGER参数,则将第7个INTEGER参数及更高版本传递给堆栈。
返回值存储在寄存器%eax中。返回值存储在寄存器%rax中。
在x86-32中,参数在堆栈上传递。最后一个参数首先被压入堆栈,直到所有参数都完成,然后执行调用指令。首先,将参数划分为类。每个参数的类确定将其传递给被调用函数的方式。
32位int ABI(应用程序二进制接口)可用于64位代码64位ABI调用不能在32位系统中使用。