2017-03-24 4 views
1

Je suis novice en matière d'assembleur. Je regarde diff de code compilé avec -g et avec -O3 fiag (optimisationcode désassemblé avec optimisation où les variables locales sont-elles conservées

En cas de code optimisé, le code désassemblé ne montre pas que les variables locales sont stockées sur la pile? appeler une fonction, il garde la trace des variables locales sur la pile et passer à suivante de la pile lors de l'exécution fonction suivante

code est désassemblé ici pour la version optimisée

(gdb) disassemble main 
Dump of assembler code for function main: 
    0x00000000004004d0 <+0>:  mov $0x1e,%eax 
    0x00000000004004d5 <+5>:  retq 
End of assembler dump. 
(gdb) disassemble foo 
Dump of assembler code for function foo: 
    0x00000000004004c0 <+0>:  lea (%rsi,%rdi,1),%eax 
    0x00000000004004c3 <+3>:  retq 
End of assembler dump. 

code Source:..

int 
foo(int a, int b) { 
    int c = 0; 
    c = a + b; 
    return (c); 
} 
int 
main() 
{ 
    int z = 10; 
    int y = 20; 
    int ret = 0; 
    ret = foo(z, y); 
    return (ret); 
} 
+1

Les variables locales peuvent être conservées dans des registres. – Barmar

+0

Si vous voulez une explication utile, vous devez montrer le code source des fonctions, alors quelqu'un peut expliquer comment les variables locales sont stockées. – Barmar

+0

Voici le code source. – bhavin

Répondre

3

C n'a pas de règles sur l'endroit où les variables locales doivent vivre - elles peuvent vivre sur la pile, dans les registres, en mémoire, ou être totalement élues.

Dans votre exemple, il semble que la plupart de vos variables locales ont été entièrement optimisées. À -O3gcc déplacer agressivement les variables dans les registres, supprimer les variables inutilisées, et ignorer les variables locales entièrement si elles ne sont que des incidents temporaires. Par exemple, dans votre foo, gcc optimisera c et stockera le résultat de l'addition directement dans le registre des résultats %eax. Notez qu'il ne compile pas du tout c = 0; dans la sortie, car il sait c est bousculé par l'instruction suivante.

En main, z et y ont connu des valeurs quand ils entrent foo, de sorte que votre compilateur inline juste la définition de foo. Le repliement et la propagation constants réduisent le main à simplement return 30;, ce qui ne nécessite aucune variable locale - c'est la sortie que vous voyez dans l'assemblage (0x1e = 30).

3

Le compilateur a remarqué que foo() est une fonction si simple qu'il peut être compilé en ligne. Puis il a vu que tous les paramètres sont constants, donc il a calculé le résultat. Ainsi, votre fonction main() a été optimisé dans l'équivalent de:

int main() { 
    return 30; 
} 

$0x1e est le nombre 30 en hexadécimal.

Et la compilation de foo() a supprimé la c variable et compilé comme si elle était simplement:

int foo(int a, int b) { 
    return a + b; 
} 

Les arguments sont passés dans les registres RSI et RDI, qui sont ajoutés, et la somme est mettre EAX à renvoyer.