Considérez le programme suivant:
3 bytes unused 3 bytes unused vvvvvvvvvvv vvvvvvvvvvv +---+---+---+---+---+---+---+---+---+---+---+---+ | a | | | | i | b | | | | +---+---+---+---+---+---+---+---+---+---+---+---+ | v +---+---+---+---+---+---+---+---+ | a | b | | | i | +---+---+---+---+---+---+---+---+ ^^^^^^^ 2 bytes unused
5 Réponses :
Le compilateur est libre de mettre en place les variables locales telles qu'il souhaite. Il n'est même pas nécessaire d'utiliser la pile. P>
Il peut stocker les variables locales dans une commande non liée à l'ordre de déclaration sur la pile s'il utilise la pile. P>
est le compilateur autorisé à effectuer cette optimisation (par la norme C etc.)? P>
- Si oui, pourquoi n'est-ce pas ci-dessus? Li> ul> blockQuote>
Eh bien, est-ce une optimisation du tout? P>
Ce n'est pas clair. Il utilise un couple d'octets moins, mais cela compte rarement. Mais sur certaines architectures, il peut être plus rapide de lire un
Char code> s'il est enregistré par mot aligné. Ainsi, mettez ensuite le
Char code> S à côté de l'autre, obligerait l'un d'entre eux au moins à ne pas être aligné par Word et faire la lecture plus lente. P>
Cela ne répond pas pleinement à la question. Un couple d'octets sur la pile d'appels peut compter lors de la mise en œuvre d'un algorithme récursif. C est la langue de la programmation des systèmes, permettant ainsi une mémoire si possible est i> une préoccupation. La question est de savoir si GCC manque une opportunité d'optimisation ou choisit un côté d'un compromis. Il est presque certainement vrai que sur Certaines architectures i>, il est plus rapide de lire un char code> d'un emplacement aligné; Mais l'assemblage est généré pour une architecture concrète. Si cette architecture n'impose pas une pénalité pour des lectures non alignées, l'optimisation manque.
Généralement dans des systèmes normaux où la vitesse compte, le mot de lecture Wise est plus rapide que le caractère de lecture sage. La perte de mémoire par rapport au gain de vitesse est ignorée. Mais dans le cas du système où la mémoire importe, comme dans différents compilateurs de croix générant exécutable (dans une signification très générique) pour une plate-forme cible particulière, l'image peut être entièrement différente. Le compilateur peut les emballer, même vérifier leur vie et leur utilisation, en fonction de celui-ci, en fonction de la bitwidth, etc., il est donc fortement dépendant de la nécessité. Mais en général, chaque compilateur vous donne la flexibilité si vous souhaitez "pack" code> heridement. Vous pouvez examiner le manuel pour cela p>
Ce ne serait pas plus efficace de mémoire si le compilateur modifierait l'ordre des variables p> blockQuote>
Il n'y a aucun moyen de dire sans parler d'une CPU spécifique, d'un système d'exploitation spécifique et d'un compilateur spécifique. En général, le compilateur fait de manière optimale. Afin d'optimiser le code de manière significative, vous avez besoin de connaissances approfondies sur le système spécifique. P>
Dans votre cas, le compilateur est probablement défini pour optimiser la vitesse dans ce cas. Il semble que le compilateur ait décidé que les adresses alignées pour chaque variable donnent le code le plus efficace. Sur certains systèmes, il n'est pas seulement plus rapide, mais également obligatoire d'allouer à des adresses égales, car certains processeurs ne peuvent gérer que l'accès aligné. p>
est le compilateur autorisé à effectuer cette optimisation (par la norme C etc.)? P> blockQuote>
Oui, la norme C n'exige même pas que les variables soient allouées. Le compilateur est totalement libre de gérer cela de quelque manière que ce soit, il souhaite et il n'a pas besoin de documenter comment ou pourquoi. Il peut allouer les variables n'importe où, cela pourrait les optimiser entièrement ou les allouer à l'intérieur des registres du processeur ou sur la pile, ou dans une petite boîte en bois sous votre bureau. P>
compilateurs avec tampon Protection de débordement de la pile ( AVERTISSEMENT: De telles fonctionnalités n'empêchent pas de compromis, ils ne font que lever les barrières d'un attaquant, mais un attaquant qualifié trouve normalement son chemin. P> / gs code> pour Microsoft's Compiler) peut réorganiser des variables comme une fonctionnalité de sécurité. Par exemple, si vos variables locales sont une matrice de grincement de taille constante (tampon) et un pointeur de fonction, un attaquant qui peut déborder le tampon pourrait également écraser le pointeur de fonction. Ainsi, les variables locales sont réorganisées de manière à ce que le tampon soit à côté du canari. De cette façon, un attaquant ne peut (directement) compromettre le pointeur de la fonction et le débordement tampon est (espérons-le) détecté par le canaris détruit. P>
est le compilateur autorisé à effectuer cette optimisation (par la norme C etc.)? P>
oui. p>
Si oui, pourquoi cela ne va-t-il pas ci-dessus? p> blockQuote>
C'est arrivé. P>
Lisez attentivement la sortie de l'assembleur soigneusement. P>
xxx pré> variable
A code> est à offset 26. Variable
B code> est décalé 27. Variable
i code> est au décalage 28. p>
Utilisation des images que vous avez apportées La mise en page est maintenant la suivante: p>
xxx pré> blockQuote>
Je n'ai vraiment pas remarqué le numéro dans le deuxième argument de la commande MOV (L | B)>. <, Merci pour cela. Eh bien, toujours drôle pourquoi GCC organise ces commandes dans cet ordre, il aurait été plus facile de noter s'il était l'inverse.
Aucune idée de la façon dont les instructions sont commandées de cette façon. Si je devais spéculer soit, c'est quelque chose à propos de deux instructions code> movb code> touchant le même mot de mémoire qui pourrait étaller (bien que nous ayons des tampons de stockage pour une raison, il est donc peu probable) ou plus susceptible de: T Peu importe, ils ont donc été générés dans l'ordre que le compilateur les a euts dans l'arbre de syntaxe interne.
En supposant que cela soit autorisé par les normes, etc., il serait alors totalement à la mise en œuvre du compilateur individuel, qu'ils le font ou non. J'imagine que cela serait contrôlé par des niveaux d'optimisation lors de la compilation.
Le compilateur / optimiseur est libre de placer les locaux partout où il le souhaite, tant qu'il ne casse pas le programme. Il est libre de placer deux variables au même endroit s'il est certain qu'ils ne sont jamais utilisés en même temps.
Avez-vous essayé de compiler avec différentes options d'optimisation? Peut-être que vous avez compilé avec les optimisations.
Fais-t-il une différence si vous utilisez
-Os code>? Avec
O3 code>, vous dites au compilateur d'utiliser des optimisations qui rendront le code plus grand, si cela le rend plus rapide.
Je pense que le compilateur optimise déjà l'espace mémoire. À partir du code de montage:
A code>,
B code> et
i code> sera à l'adresse 26 (% ESP), 27 (% ESP) et 28 (% ESP).
Toute discussion sur l'optimisation est complètement inutile sans un système spécifique à l'esprit. J'essaie de lire l'esprit de l'opération ... Hmm ... Ceci est un système Linux ou Windows sur un dérivé Intel X86 32 bits.
@Lundin c'est Windows 64 bits sur un noyau Intel i5 avec Mingw GCC