2010-03-05 3 views
1

Quelqu'un peut-il m'expliquer l'assembly généré par GCC des codes C++ suivants? En particulier, la signification de setg et test dans les codes. THX!Aider à comprendre une partie de ce code d'assemblage généré

codes .cpp:

1 /*for loop*/ 

2 int main() 

3 { 
4  int floop_id; 

5  for(floop_id=100;floop_id>=1;floop_id--) 
6  {} 
7  return 0; 
8 } 

codes d'assemblage:

3  push %ebp    
3  mov %esp, %ebp   
3  sub $0x10,%esp   
5  movl $0x64,-0x4(%ebp) 
5  jmp 8048457<main+0x13> 
5  subl $0x1,-0x4(%esp)  
5  cmpl $0x0,-0x4(%esp)  
5  setg %al     
5  test %al, %al   
7  mov $0x0,%eax   
8  leave     
8  ret 

Répondre

3

cmpl $0x0,-0x4(%esp); setg %al moyens comparent -0x4(%esp) (floop_id dans le code) par rapport à 0, et mettre %al-1 si elle est g rand, ou 0 sinon.

test %al, %al ici ne fait rien. Je ne sais pas pourquoi c'est dans l'assemblée. (Normalement, test une valeur avec lui-même est utilisée pour obtenir le signum de la valeur (ie, zéro, positif ou négatif), mais le résultat de ceci n'est pas utilisé ici. branche conditionnelle (pour implémenter la boucle), mais vu que votre boucle est vide, elle a été supprimée.)

+0

Merci pour votre réponse! J'ai trouvé une chose intéressante: quand je compile les codes c avec gcc en utilisant le même code ci-dessus, les codes d'assemblage générés est différent: cmpl 0x0 $, -0x4 (% esp) jg 80483a3 il il n'y a pas d'instructions de setg et de test. Mais les autres sont les mêmes. Connais-tu les raisons possibles? THX! – martin

+0

@martin: Je suppose que le frontend C a choisi de ne pas "dépouiller" le corps de la boucle vide, contrairement à l'interface C++. :-) Essayez également de compiler avec différents indicateurs d'optimisation (par exemple, '-O1',' -O2'). Vous verrez des résultats radicalement différents. –

+0

J'ai essayé avec différents drapeaux d'optimisation, mais l'assemblage est le même. désolé, qu'est-ce que vous voulez dire par enlever le corps de la boucle vide? comment cela affecte-t-il les codes d'assemblage? Merci beaucoup! – martin

0

Votre code d'assemblage généré n'a pas le cycle dedans (apparemment le compilateur a décidé qu'il n'était pas nécessaire), mais il semble contenir quelques restes libres de ce cycle. Il y a des bits qui chargent 100 dans une variable, soustrayez-en 1, comparez-la avec 0. Mais il n'y a pas d'itération réelle dans le code.

Essayer de trouver une logique dans cet exercice est inutile. Le compilateur, évidemment, a décidé d'enlever tout le cycle. Mais pourquoi il a laissé des "débris" derrière n'est pas clair. Je dirais que ce qui reste dans le code est inoffensif, mais en même temps a autant de sens qu'une valeur d'une variable initialisée.

BTW, où le jmp inconditionnel conduire à? Ce n'est pas clair à cause de votre démontage. Ne va-t-il pas tout de suite à 7?

Questions connexes