I compiled the following C code:
typedef struct {
long x, y, z;
} Foo;
long Bar(Foo *f, long i)
{
return f[i].x + f[i].y + f[i].z;
}
with the command gcc -S -O3 test.c
. Here is the Bar function in the output:
.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:
I have a few questions about this assembly code:
- What is the purpose of "
pushq %rbp
", "movq %rsp, %rbp
", and "popq %rbp
", if neitherrbp
norrsp
is used in the body of the function? - Why do
rsi
andrdi
automatically contain the arguments to the C function (i
andf
, respectively) without reading them from the stack? I tried increasing the size of Foo to 88 bytes (11
long
s) and theleaq
instruction became animulq
. Would it make sense to design my structs to have "rounder" sizes to avoid the multiply instructions (in order to optimize array access)? Theleaq
instruction was replaced with:imulq $88, %rsi, %rcx