Я скомпилировал следующий код 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 длинных
с), и инструкция leaq
стала imulq
. Имеет ли смысл проектировать мои структуры так, чтобы они имели «круглые» размеры, чтобы избежать инструкций умножения (чтобы оптимизировать доступ к массиву)? Инструкция leaq
заменена на:
imulq $88, %rsi, %rcx