基于PowerPC 的UNIX System V ABI

来源:互联网 发布:笑笑淘宝店倒闭 编辑:程序博客网 时间:2024/06/10 18:56
1.1 基于PowerPC 的UNIX System V ABI
System V Application Binary Interface定义了已编译的应用程序的接口,目的是建立在遵循System V定义的系统中应用程序标准的二进制接口。这些系统包括UNIX SystemV R4。
基于PowerPC的System V ABI在通用ABI的基础上考虑PowerPC的架构,做了扩展。GNU工具集提供的编译链接工具也遵循这一标准。
1.1.1 寄存器
PowerPC架构提供了32个32 bits宽度的通用寄存器,32个64 bits宽度的浮点寄存器和一些专用寄存器。这些寄存器都是所有程序全局可以访问的,主要的寄存器如下表所示:
表1-1 PowerPC架构寄存器及其用途
寄存器
用途
r0
可变寄存器,在函数链接的时候可能被修改
r1
堆栈指针,总是有效的
r2
系统保留的寄存器
r3-r4
可变寄存器,用于传递参数和返回值
r5-r10
可变寄存器,用于传递参数
r11-r12
可变寄存器,在函数链接时可能被修改
r13
小数据区域(Small data area)的指针寄存器
r14-r30
用于局部变量
r31
用于局部变量或者“环境指针”
f0
可变寄存器
f1
可变寄存器,用于传递参数和返回值
f2-f8
可变寄存器,用于传递参数
f9-f13
可变寄存器
f14-f31
用于局部变量
CR0-CR7
条件寄存器,每个有4 bits的宽度
LR
链接寄存器
CTR
计数寄存器
XER
定点异常寄存器
FPSCR
浮点状态和控制寄存器
 
寄存器r1、r14~r31和f14~f31为非可变的寄存器,表示它们属于调用函数。如果被调函数要改变它们的值,则需要在函数返回之前恢复它们的值。
寄存器r0、r3~r12和f0~f13以及特殊寄存器CTR、XER为可变寄存器,表示它们在函数调用过程中是没有保护的,值随时可能变化。尤其是,r0、r11和r12可能在交叉调用中改变。所以在函数调用之后,这些寄存器的值可能发生变化。
寄存器r2保留给系统使用,应用程序不能修改其值。
寄存器r13为小数据区域的指针,用于在启动代码在执行时引用小数据区域中的数值。所谓的小数据区域指的是可执行程序数据段的一部分,包含.sdata和.sbss段中的数据,其基址可以放在r13中,偏移不超过16 bits的寻址范围。
r31用于“环境指针”。
条件寄存器中CR2、CR3和CR4为非可变寄存器,其值需保护,其它为可变寄存器。
被调用函数可能改变FPSCR寄存器的VE、OE、UE、ZE、XE、NI和RN位,其它位可变。
 
在标准的函数调用过程中,一般使用如下的规则:
l              r1             存储堆栈指针,维持16字节对齐。其总是指向地址最低的已分配的堆栈帧,地址中的内容指向上一个已分配的堆栈帧。如果需要,可由被调用函数减少其值。
l              r3~r10 f1~f8    用于传递参数,另外r3、r4和f1还用于返回值。
l              CR[6](CR1,“浮点无效异常”) 在调用变参函数时,应设置该位。
l              LR             包含被调用函数正常返回时的地址。
BA_OS信号可能中断程序的处理,但编程和编译时都不需要考虑其对寄存器的影响,可假定所有寄存器都得到了保存。
1.1.2 堆栈
堆栈的组织如下图所示:
 
1.1.3 参数传递
像PowerPC这样的RISC处理器,使用寄存器的方式来传递参数。这要比直接在内存中构造参数列表,再将其压入到堆栈中要来得有效。如果调用函数将参数放入到寄存器,并将其传递给被调用函数相同的寄存器,而被调用函数按照同样的约定来解析参数,这样,就能大大降低对存储器的访问。从上述来看,处理器架构寄存器的多少决定了有多少个参数可以采用这种方式来传递参数。
在PowerPC架构中,共有8个GPR和8个FPR来传递参数。如果入参不足这么多个,则不会对剩下的寄存器赋值,它们的值是未知的。
在最坏的情况下,当传递的参数无法放入到GPR或者FPR中时,只需要在堆栈中分配足够存放参数的空间即可。这些参数是自右到左入栈的。
1.1.4 参数列表
一些可移植的程序依赖于参数传递机制,需要(1)所有参数是依赖于堆栈传递的,(2)堆栈中的参数是升序排列的。虽然这样的程序是不具备可移植性,但在很多应用中都是这样工作的。然而,PowerPC不支持这样的应用,因为部分参数是通过寄存器来传递参数。在PowerPC及其它架构中,C程序应该按照<stdarg.h>或者 <varargs.h>来处理参数列表,来实现可移植性。
如果一个可变参的函数使用到了FPR,那么调用函数应该将条件寄存器的第6位置一,否则强烈推荐将其置零。原因有二:第一、可变参函数需要探测条件寄存器的第6位是否为一来决定是否在内存中存储浮点参数寄存器,因而在没有浮点参数时,运行这些函数将更有效率;第二、如果程序不使用浮点,就不需要查询浮点状态,就不需要在上下文切换的时候花费保存和恢复的资源。ANSI C要求这些变参函数必须声明包含省略号标识的原型,但是编译器的厂商进行了扩展以允许非ANCI C的程序在命令行声明可变参函数,或者干脆将所有没有经过声明的函数当作可变参函数。
1.1.5 返回值
浮点和双精度型的返回值在f1中返回。
整型、长整型、枚举、短整型,和字符,或者指向任一类型的指针,以及有符号和无符号的整型在r3中返回。
小等于8字节的结构体或者联合体在r3、r4中返回,低地址的值存放在r3中,高地址的值存放在r4中,不足的位数其值是不确定的。
支持long long 和 unsigned long long类型,低地址的值存放在r3中,高地址的值存放在r4中返回。
long double和那些不满足在寄存器中返回的结构体或者联合体在调用函数开辟的buffer中返回。该buffer的地址在r3中当作第一个参数隐藏传递,入参则在r4开始传递。
 
原创粉丝点击