gcc堆栈排列的建议(译文)
参考:https://gcc.gnu.org/ml/gcc/2007-12/msg00503.html
英语水平有限,翻译有些许瑕疵
一. 目标动机
一些局部变量(如uu m128类型或用对齐方式标记)属性)要求堆栈在大于默认值的边界处对齐堆栈边界。当前的GCC部分支持这一点,但有局限性。我们是提出一个新的设计来全面解决这个问题。
二. 当前采用机制
当前gcc支持大于默认堆栈的方法有两种:
一种是确保堆栈在程序入口的时候对齐, 确保每个non-leaf 函数的帧大小对齐,但是当链接到libs或使用psABI编译器编译对象的时候,这种方法是不起作用的
另一种方法是,如果函数的入口点被标记为 _attribute_((force_align_arg_pointer))或提供了-mstackreagn选项,则调整堆栈对齐。这种方法保证了大多数情况下的对齐,但存在以下问题和限制:
*仅支持16字节对齐
*在每个函数序言处调整堆栈对齐影响性能,因为并非所有函数都需数据对齐。实际上,通常只有那些局部定义了SSE变量的函数(由用户或编译器生成的内部临时变量声明)需要相应的对齐。
*在需要堆栈对齐时,不支持用于案例的x86_64( 大于16字节)
*需要前后代码来调整堆栈对齐
*不适用于嵌套函数
三. 新方案设计
在这里,我们提出了一种新的设计来完全支持堆栈对齐,同时
克服上述问题。新设计将
*支持任意对齐值,包括4、8、16、32…
*仅在必要时调整函数堆栈对齐
*初始开发将在i386和x86_上进行,但可以扩展至其他平台
*与动态堆栈分配(alloca)、嵌套函数、寄存器参数传递、pic代码和调用等特殊功能共存优化
*能够调试和展开堆栈
3.1 支持任意对齐值
不同的源代码和优化需要不同的堆栈对齐,
如下表所示:
功能对齐(字节)
i386_ABI 4
x86_64_ABI 16
char 1
short 2
int 4
long 4/8*
long long 8
__m64 8
__m128 16
float 4
double 8
long double 4/16*
3.2 仅在必要时调整功能堆栈对齐
1)STACK_BOUNDARY: 以位为单位的堆栈边界,由硬件强制执行,i386为32,x86_为64。它是最小堆栈边界。它是固定的。
2)PREFERRED_STACK_BOUNDARY: 它在调用函数时设置堆栈对齐方式。它可以在命令行设置,对堆栈没有影响,功能入口对齐,要求PREFERRED >= STACK,默认情况下设置 ABI_STACK_BOUNDARY
3)这种设计将定义更多的宏,或者不明确的概念,在代码中定义:
ABI_STACK_BOUNDARY:指定的堆栈边界,通过psabi,32用于i386,128用于x86_, ABI_STACK_BOUNDARY >=STACK_BOUNDARY,