c - 当我们将结构传递给函数时会发生什么?
问题描述
假设我们将一个结构传递给一个函数:
struct rect {
long llx;
long lly;
};
long test() {
struct rect oldRect;
oldRect.llx = 1;
oldRect.lly = 2;
struct rect newRect = make_double(oldRect);
return newRect.llx * newRect.lly;
}
struct rect make_double(struct rect r) {
r.llx *= 2;
r.lly *= 2;
return r;
}
为了更深入地了解传递结构变量时实际发生的情况,我将 C 代码编译为程序集,如下所示:
// remove some directives that affects readibility
test:
subq $56, %rsp
movl $1, %edi
movl $2, %esi
call make_double
imulq %rdx, %rax
addq $56, %rsp
ret
make_double:
leaq (%rsi,%rsi), %rdx
leaq (%rdi,%rdi), %rax
ret
有趣的是,当传递 struct 时oldRect
,gcc 实际上将其成员复制到寄存器中,这些寄存器将用作函数中的参数make_double
。所以我的问题是:
Q1-只是确认当传递一个结构变量时,编译器会获取结构的所有成员并将它们复制到寄存器,我的理解/观察是否正确?
Q2-由于编译器oldRect
通过递减堆栈指针为 分配内存空间,但编译器实际上并没有分别将 1 和 2 分别推送到oldRect.llx
,oldRect.lly
如果是这种情况,编译器甚至不需要首先递减堆栈指针?
Q3-我对这条指令有点困惑:
subq $56, %rsp
为什么我们必须将堆栈指针减 56?的大小struct rect
是16,不需要填充,为什么不需要
subq $16, %rsp
解决方案
推荐阅读
- javascript - 在windows上编译nodeJs项目
- numpy - 使用 numpy 提高 FOR 循环性能
- user-interface - 如何准确命名 UI 组件?
- python - 使用 setup.py 脚本安装时找不到 PyQt5.sip 模块
- typescript - Jest 在使用 Material UI 中的 TextField 时遇到了意外的令牌
- flutter - 使用 Flutter DateTime 和 Timer 时遇到不一致的行为
- wordpress - 从重定向中排除文件夹
- javascript - 如何在谷歌翻译器中设置默认语言?
- javascript - 检查字符串数组中出现哪些关键字(10k 个单词)的最有效方法?
- sql - 在 SQL 或 Excel 中对多级组织层次结构进行分组