我编译了以下 C 代码:
typedef struct {
long x, y, z;
} Foo;
long Bar(Foo *f, long i)
{
return f[i].x + f[i].y + f[i].z;
}
用命令gcc -S -O3 test.c
。这是输出中的 Bar 函数:
.section __TEXT,__text,regular,pure_instructions
.globl _Bar
.align 4, 0x90
_Bar:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
leaq (%rsi,%rsi,2), %rcx
movq 8(%rdi,%rcx,8), %rax
addq (%rdi,%rcx,8), %rax
addq 16(%rdi,%rcx,8), %rax
popq %rbp
ret
Leh_func_end1:
我对这个汇编代码有几个问题:
- 如果函数主体中既不使用也不使用“
pushq %rbp
”、“movq %rsp, %rbp
”和“ ”的目的是什么?popq %rbp
rbp
rsp
- 为什么
rsi
并rdi
自动包含 C 函数的参数(i
和f
,分别)而不从堆栈中读取它们? 我尝试将 Foo 的大小增加到 88 字节(11
long
秒)并且leaq
指令变成了imulq
. 将我的结构设计为具有“更圆”的大小以避免乘法指令(以优化数组访问)是否有意义?该leaq
指令被替换为:imulq $88, %rsi, %rcx