Certains d'entre eux pourraient être l'espace pour les paramètres sortants, si votre fonction en appelle d'autres; certains d'entre eux pourraient être un espace temporaire pour les valeurs déversées dans les registres; certains d'entre eux pourraient être rembourrés. Cela dépendra beaucoup de la version du compilateur et des indicateurs d'optimisation.
est ici un code non-sens simple illustration:
extern int foo(int a, int b);
int bar(int c)
{
char s[12];
s[0] = foo(c, 123);
return 456;
}
Ici, il est compilé avec aucune optimisation utilisant gcc 4.3.2 sur une machine Debian Lenny:
bar:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $123, 4(%esp)
movl 8(%ebp), %eax
movl %eax, (%esp)
call foo
movb %al, -12(%ebp)
movl $456, %eax
leave
ret
Comme votre code, il est l'allocation 24 octets. Voici ce qu'ils sont utilisés pour:
Stack while running bar()
: :
+-------------------------+
| incoming parameter: c | 8(%ebp)
+-------------------------+ ---
| return address | 4(%ebp) ^
+-------------------------+ |
| old %ebp | (%ebp) |
+-------------------------+ | bar()'s stack
| s[8]..s[11] | -4(%ebp) | frame: 32 bytes
+-------------------------+ |
| s[4]..s[7] | -8(%ebp) |
+-------------------------+ |
| s[0]..s[3] | -12(%ebp) |
+-------------------------+ | Stack while running foo()
| (unused) | 8(%esp) | : :
+-------------------------+ | +-------------------------+
| outgoing parameter: 123 | 4(%esp) | | incoming parameter: b |
+-------------------------+ | +-------------------------+
| outgoing parameter: c | (%esp) v | incoming parameter: a |
+-------------------------+ --- +-------------------------+
| return address |
+-------------------------+
| old %ebp |
+-------------------------+
: locals for foo() :
Un peu d'expérience montrera que si s[]
augmente, il mangera dans l'espace inutilisé; par exemple. si elle est de 13 octets, la trame de la pile a la même taille, mais s[]
démarrera un octet plus tôt (à -13(%ebp)
) - jusqu'à 16 octets, où toute la pile allouée sera réellement utilisée. Si s
est déclaré comme s[17]
, le compilateur allouera 40 octets de pile au lieu de 24.
Cela est dû au fait que le compilateur conserve la taille totale du cadre de la pile (tout à gauche du diagramme ci-dessus, à l'exception du paramètre, qui est vraiment en bas de la pile de l'appelant) arrondi à un multiple de 16 octets. (Voir la documentation gcc pour l'option -mpreferred-stack-boundary
.)
Il serait plus facile de répondre si vous montriez le code C –
Je suppose que c'est difficile à dire sans voir votre code d'entrée. –
F() {tableau [12] ...}, l'assemblage ci-dessus est l'appel à sa fonction – newprint