Chcę poznać konwencję wywoływania C. Aby to zrobić, napisałem poniższy kod:Zrozumienie C rozmontowanego połączenia
#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;
}
Następnie użyłem GCC za pomocą następującego polecenia:
gcc -S test3.c
i wymyślił jego montażu. Nie pokażę całego kodu, ale mam wkleić kod funkcji my_func. Jest to:
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
O ile zrozumiałem, to co się dzieje: Najpierw dzwoniący baza wskaźnik jest wpychana do stosu, a jej wskaźnik stosu jest nowy wskaźnik podstawy do utworzenia stosu dla nowych funkcjonować. Ale reszta nie rozumiem. O ile mi wiadomo, argumenty (lub wskaźnik do argumentu) są przechowywane w stosie. Jeśli tak to, co jest celem drugiego instrukcji,
movq -24(%rbp), %rax
Tutaj zawartość rejestru% RAX zostanie przeniesiona do adresu 24 bajtów od adresu w rejestrze% RBP. Ale co jest w% rax ???? Nic tam nie jest początkowo przechowywane? Myślę, że jestem zdezorientowany. Pomóż zrozumieć, jak działa ta funkcja. Z góry dziękuję!
skompilować z 'gcc -fverbose-ASM -S' a może nawet' gcc -fverbose-ASM -O -S'; zobacz także [tę odpowiedź] (http://stackoverflow.com/a/16088155/841108), która podaje * lot * referencji. –
Dzięki za wszystkie referencje i końcówkę kompilacji. – user2290802