我正在研究ppc32和ppc64架构,以便为我的编译器实现一个新的后端,但我对函数的prolog有疑问,我已经阅读了几个关于PowerPC的文档,但我读到的关于该堆栈的信息很少。以及它到底是如何工作的。因此,为了更好地理解,我使用godbolt.org检查函数是如何编译的,并注意到以下几点:
一个带有4个int类型参数的函数,将为prolog生成以下代码:
test1(int, int, int, int):
stwu 1,-32(1)
stw 31,28(1)
mr 31,1
stw 3,8(31)
stw 4,12(31)
stw 5,16(31)
stw 6,20(31)一个具有5个int类型参数的函数,使用以下代码:
test2(int, int, int, int, int):
stwu 1,-48(1)
stw 31,44(1)
mr 31,1
stw 3,8(31)
stw 4,12(31)
stw 5,16(31)
stw 6,20(31)
stw 7,24(31)包含10个int类型参数的函数使用以下代码:
test4(int, int, int, int, int, int, int, int, int, int):
stwu 1,-48(1)
stw 31,44(1)
mr 31,1
stw 3,8(31)
stw 4,12(31)
stw 5,16(31)
stw 6,20(31)
stw 7,24(31)
stw 8,28(31)
stw 9,32(31)
stw 10,36(31)我注意到,对于包含4个和5个参数的函数,堆栈偏移量的计算在以下指令中发生了更改。
; 4 parameters
stwu 1,-32(1)
stw 31,28(1)
; 5 parameters
stwu 1,-48(1)
stw 31,44(1)但是在10个参数的函数中,偏移量与5个参数的函数保持相同,并且只使用8个'stw‘指令来加载参数,其余的参数稍后使用'lwz’指令加载
为什么会发生这种情况?我认为这是堆栈上的一些东西,但是什么?
注:我在这个问题中展示的汇编代码是由GCC 4.8.5 PowerPC生成的
发布于 2020-03-11 15:52:49
你提到过:
仅使用了8条'stw‘指令来加载参数
,
,参数已经在寄存器r3-r10中,因为这是它们传递给函数的方式。
相反,这些stw指令将函数参数存储到堆栈中。不清楚为什么编译器在没有可用的函数代码的情况下将参数复制到堆栈中,但是假设您的函数很简单,我猜您禁用了优化,因此它将所有内容保存到堆栈框架中。
8个参数和10个参数版本的前言没有区别的原因是只有前8个参数是通过寄存器传递的。任何进一步的参数都被传递到调用方的堆栈上,并通过lwz指令加载。
您应该阅读ppc的ELF ABI specification,它定义了函数调用顺序(第3-14节),以及其他内容。虽然您没有指定针对哪个ABI规范进行编译,但在这一方面不应该与ELF规范有很大的不同。
https://stackoverflow.com/questions/59557799
复制相似问题