Non, il ne peut pas connaître la valeur de esp
à l'avance. Prenons par exemple une fonction récursive, c'est-à-dire
une fonction qui s'appelle elle-même. Supposons qu'une telle fonction a plusieurs paramètres qui sont transmis via la pile. Cela signifie que chaque argument prend de l'espace sur la pile, modifiant ainsi la valeur du registre esp
.
Maintenant, lorsque la fonction est entrée, la valeur exacte de esp
dépendra du nombre de fois que la fonction s'est appelée elle-même précédemment, et il est impossible que le compilateur puisse le savoir au moment de la compilation. Si vous en doutez, prenez une fonction telle que celle-ci:
void foobar(int n)
{
if (rand() % n != 17)
foobar(n + 1);
}
Il n'y a aucun moyen le compilateur serait assez intelligent à l'avance pour savoir si la fonction elle-même appeler une fois de plus.
Si le compilateur voulait déterminer à l'avance esp
, il devrait effectivement créer une version de la fonction pour chaque valeur possible pour esp
.
L'explication ci-dessus ne prend en compte qu'une seule fonction. Dans un scénario réel, un programme a de nombreuses fonctions qui s'interpénètrent les unes sur les autres, ce qui se traduit par des «graphiques d'appel» assez complexes. Ceci avec (entre autres choses) une logique de programme imprévisible signifie que le compilateur devrait créer un grand nombre de versions de chaque fonction, juste pour optimiser sur esp
- ce qui n'a évidemment aucun sens.
P.S .: maintenant quelque chose d'autre. Vous n'avez pas vraiment besoin d'optimiser [esp+N]
du tout, car il ne devrait pas prendre plus de temps CPU que le plus simple [esp]
... du moins pas sur les processeurs Intel Pentium. On pourrait dire qu'ils contiennent déjà des optimisations pour exactement cela et des scénarios encore plus compliqués. Si vous êtes intéressé par les processeurs Intel, je vous suggère de rechercher dans la documentation quelque chose appelé MOD R/M et SIB octet d'une instruction machine, par ex.here for the SIB byte ou here ou, bien sûr, dans la documentation officielle des développeurs d'Intel.
Juste une question de plus, si vous n'utilisiez aucun appel de fonction récursive dans le programme entier, cela pourrait-il être fait sans utiliser l'adressage indirect? –
_ @ b-gen-jack-o-neill: _ Ça rendrait les choses plus faciles. Disons qu'il est clair qu'une fonction 'caller' appelle votre fonction cible' f'. Ensuite, 'esp' pourrait être calculé sur la base de la valeur' esp' supposée pour 'caller', plus éventuellement l'espace requis par les variables locales de' caller' et les arguments de 'f'. (Il peut en fait ne pas être si simple.) La fonction récursive ci-dessus pourrait être transformée en fonctions * n * + 1 presque identiques (une par itération, où * n * est le nombre de fois que la fonction s'appelle elle-même; la valeur supposée pour 'esp'). – stakx
_ @ b-gen-jack-o-neill: _ Veuillez également lire le P.S. ajouté. à ma réponse. Il répond à la question assez importante de savoir si vous devez "optimiser" '[esp + N]' du tout. – stakx