Я хочу узнать о конвенции C вызова. Для этого я написал следующий код:Понимание C разобранным звонком
#include <stdio.h>
#include <stdlib.h>
struct tstStruct
{
void *sp;
int k;
};
void my_func(struct tstStruct*);
typedef struct tstStruct strc;
int main()
{
char a;
a = 'b';
strc* t1 = (strc*) malloc(sizeof(strc));
t1 -> sp = &a;
t1 -> k = 40;
my_func(t1);
return 0;
}
void my_func(strc* s1)
{
void* n = s1 -> sp + 121;
int d = s1 -> k + 323;
}
Затем я использовал GCC с помощью следующей команды:
gcc -S test3.c
и придумал его сборки. Я не буду показывать весь код, который я получил, но скорее вставлю код для функции my_func. Именно это:
my_func:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -24(%rbp)
movq -24(%rbp), %rax
movq (%rax), %rax
addq $121, %rax
movq %rax, -16(%rbp)
movq -24(%rbp), %rax
movl 8(%rax), %eax
addl $323, %eax
movl %eax, -4(%rbp)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
Насколько я понял, это то, что происходит: Сначала звонящие базовый указатель помещается в стек и его указатель стека сделан новый указатель базы для настройки стеки для нового функция. Но тогда все остальное я не понимаю. Насколько мне известно, аргументы (или указатель на аргумент) хранятся в стеке. Если это так, какова цель второй команды,
movq -24(%rbp), %rax
Здесь содержание регистра% RAx перемещается по адресу 24 байт от адреса в регистре% РСП. Но что в% rax ???? Ничего изначально не хранится там? Кажется, я в замешательстве. Пожалуйста, помогите понять, как работает эта функция. Спасибо заранее!
Compile с 'Gcc -fverbose-ASM -S' и, возможно, даже' НКУ -fverbose-ASM -O -S'; см. также [этот ответ] (http://stackoverflow.com/a/16088155/841108), который дает * много * ссылок. –
Спасибо за все ссылки и подсказку компиляции. – user2290802