64 位应用程序使用可执行和链接格式 (Executable and Linking Format, ELF64) 进行描述,使用该格式可以全面地描述大型应用程序和较大地址空间。
SPARC V9。《SPARC Compliance Definition Version 2.4》中包含 SPARC V9 ABI 的详细信息。此文档描述了 32 位 SPARC V8 ABI 和 64 位 SPARC V9 ABI,可以从 SPARC International 公司的网站 www.sparc.com 上获取。
以下列出了 SPARC V9 ABI 的特征:
SPARC V9 ABI 允许充分利用所有 64 位 SPARC 指令和数据宽度为 64 位的寄存器。许多新的相关指令都是对现有 V8 指令集的扩展。请参见《The SPARC Architecture Manual, Version 9》。
基本调用约定相同。调用方的前六个参数放在外部寄存器 %o0-%o5 中。SPARC V9 ABI 对于较大的寄存器文件仍会使用寄存器窗口,以便使函数调用操作“降低成本”。结果将返回到 %o0 中。由于所有的寄存器现在都被视为 64 位,因此 64 位值现在可以通过单寄存器而不是寄存器对传送。
栈的布局不同。除了基本单元大小从 32 位增加到 64 位外,各种隐藏的参数术语均已删除。返回地址仍是 %o7 + 8。
%o6 仍然称作栈指针寄存器 %sp,%i6 称作帧指针寄存器 %fp。但是,%sp 和 %fp 寄存器距离栈的实际内存位置的偏移量(称为栈偏移量)是常量。栈偏移量的大小为 2047 个字节。
指令大小仍为 32 位。因此,生成地址常量需要更多指令。该调用指令无法再使用该调用指令在地址空间中的任何位置建立分支,因为它只能达到离 %pc ( 2 GB 的位置。
现在,整数乘除函数可以完全在硬件中实现。
结构的传递和返回以不同的方式实现。小型数据结构和某些浮点参数现在直接在寄存器中传递。
通过用户陷阱,用户陷阱处理程序可处理非特权代码中的某些陷阱(而不是传送信号)。
所有数据类型现在都与其长度对齐。
许多基本派生类型会更长,因此,许多系统调用接口数据结构现在具有不同的长度。
系统中存在两组不同的库:用于 32 位 SPARC 应用程序的库和用于 64 位 SPARC 应用程序的库。
SPARC V9。对于开发者来说,SPARC V9 ABI 的一个重要特征就是栈偏移量。 对于 64 位 SPARC 程序来说,必须向帧指针和栈指针中都添加大小为 2047 个字节的栈偏移量,才能达到栈帧的实际数据。 请参见下图。
有关栈偏移量的更多信息,请参见 SPARC V9 ABI。
SPARC V9。对于 64 位应用程序,尽管起始地址和寻址限制大不相同,但地址空间的布局与 32 位应用程序的布局密切相关。与 SPARC V8 一样,SPARC V9 栈从地址空间的顶部开始减小,而堆则从底部开始扩展数据段。
下图说明了为 64 位应用程序提供的缺省地址空间。地址空间中标记为保留空间的区域可能不是由应用程序进行映射。这些限制在将来的系统中可能会有所放松。
上图中的实际地址描述了特定计算机上的特定实现,仅供参考。
缺省情况下,64 位程序与起始地址 0x100000000 链接,整个程序(包括其文本、数据、堆、栈和共享库)将超过 4 GB。这有助于确保 64 位程序正确无误,方法是使其在截断其任何指针时在较低的 4 GB 地址空间中出错。
尽管 64 位程序会链接到 4 GB 以上的地址空间,但是仍可以通过使用链接程序映射文件以及编译器或链接程序的 -M 选项,将其链接到 4 GB 以下的地址空间。/usr/lib/ld/sparcv9/map.below4G 中提供了一个用来将 64 位 SPARC 程序链接到 4 GB 以下地址空间的链接程序映射文件。
有关更多信息,请参见 ld(1) 链接程序手册页。
SPARC V9。编译器针对不同目的提供了不同的代码模型,旨在提高性能并减少 64 位 SPARC 程序中代码的大小。代码模型由以下因素确定:
可放置性(绝对独立代码与位置无关代码)
代码大小(< 2 GB)
位置(地址空间中的低、中或任意位置)
外部对象引用模型(小或大)
下表介绍了可用于 64 位 SPARC 程序中的不同代码模型。
表 6–1 代码模型说明:SPARC V9
代码模型 |
可放置性 |
代码大小 |
位置 |
外部对象引用模型 |
---|---|---|---|---|
abs32 |
绝对 |
< 2 GB |
低(低 32 位地址空间) |
无 |
abs44 |
绝对 |
< 2 GB |
中(低 44 位地址空间) |
无 |
abs64 |
绝对 |
< 2 GB |
任意位置 |
无 |
pic |
PIC(位置无关代码) |
< 2 GB |
任意位置 |
小(<= 1024 个外部对象) |
PIC |
PIC |
< 2 GB |
任意位置 |
大(<= 2**29 个外部对象) |
在某些情况下,可以使用较小的代码模型实现较短的指令序列。 在绝对代码中执行静态数据引用所需的指令数在不同的代码模型中各不相同:在 abs32 代码模型中最少,在 abs64 代码模型中最多,在 abs44 代码模型中居于两者之间。 同样,在执行静态数据引用时,pic 代码模型使用的指令比 PIC 代码模型使用的要少。 因此,代码模型越小,代码块越小,对于无需利用较大代码模型的更完整功能的程序,还可能会提高其性能。
要指定要使用的代码模型,应使用 -xcode=<model> 编译器选项。目前,对于 64 位对象,编译器在缺省情况下使用 abs64 模型。 通过使用 abs44 代码模型可以优化代码,此时将使用较少的指令,并且仍能涵盖当前的 UltraSPARC 平台所支持的 44 位地址空间。
有关代码模型的更多信息,请参见 SPARC V9 ABI 和编译器文档。
对于使用 abs32 代码模型编译的程序,必须使用 -M /usr/lib/ld/sparcv9/map.below4G 选项将其链接到 4 GB 以下的地址空间。