#include <iostream>
struct st1 { int vi[4]; };
struct st2 { char vd[4]; };
class cl {
char v1[4];
char v3[4];
long v2[4];
public:
cl(st1 ss);
cl(st1& s1, int ar2[]);
void elab1(char[],st2);
};
void cl::elab1(char ar1[],st2 st)
{
st.vd[0]='a';
st.vd[1]=3;
st.vd[2]=3;
st.vd[3]=3;
ar1[0]=3;
}
我正在将代码从 C++ 转换为汇编,但我无法理解参数传递在汇编中是如何精确执行的。我已经阅读了 System V ABI,但对于像我上面写的那样的特殊情况并不清楚。
除了系统V pdf之外,是否存在任何来源,其中详细解释了数据结构的参数传递是如何完成的?谢谢
我还复制了https://godbolt.org/上的代码: char ar1[] 作为指针传递,这对我来说是正确的,而 st2 内的字符数组不作为指针传递至 &vd[0]。
cl::elab1(char*, st2):
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movl %edx, -20(%rbp)
movb $97, -20(%rbp)
movb $3, -19(%rbp)
movb $3, -18(%rbp)
movb $3, -17(%rbp)
movq -16(%rbp), %rax
movb $3, (%rax)
nop
popq %rbp
ret
这是翻译后的汇编代码,来自 https://godbolt.org/。
非常感谢您的帮助。
我不清楚的是 %rdi 包含什么,因为当我试验代码时,this 指针被传递到 %rsi。
经过一些研究,我找到了我的问题的答案:
- 如果类型具有 MEMORY 类,则调用者为返回值提供空间 并在 %rdi 中传递此存储的地址,就好像它是传递给 功能。实际上,该地址成为“隐藏”的第一个参数。这个存储 不得通过除此参数之外的其他名称与被调用者可见的任何数据重叠。
来源:第 27 页 System V ABI (pdf) 链接