Printf l'adresse actuelle dans un programme C
Imaginer que j'ai suivantes simple programme C:
int main() {
int a=5, b= 6, c;
c = a +b;
return 0;
}
Maintenant, je voudrais savoir l'adresse de l'expression c=a+b, qui est l'adresse du programme
où cet ajout est effectué. Est-il possible que je puisse utiliser printf?
Quelque chose le long de la ligne:
int main() {
int a=5, b= 6, c;
printf("Address of printf instruction in memory: %x", current_address_pointer_or_something)
c = a +b;
return 0;
}
Je sais comment j'ai pu trouver l'adresse par l'utilisation de gdb et ensuite la ligne info de fichier.c:ligne. Cependant, je voudrais savoir si je pouvais aussi le faire directement avec le printf.
Il serait utile de savoir qui de l'architecture du processeur et le compilateur que vous utilisez. Le consensus semble être que il n'y a pas vraiment portable façon de le faire.
n'est-il pas possible que l '"instruction" vous êtes à la recherche à la réalité se traduit par une série d'instructions de montage, couvrant une plage d'adresses?
n'est-il pas possible que l '"instruction" vous êtes à la recherche à la réalité se traduit par une série d'instructions de montage, couvrant une plage d'adresses?
OriginalL'auteur | 2009-05-14
Vous devez vous connecter pour publier un commentaire.
Dans gcc, vous pouvez prendre l'adresse d'une étiquette en utilisant le && de l'opérateur. Donc, vous pourriez faire ceci:
Le résultat de &&somme est la cible de l'instruction de saut qui serait émise si vous avez un
goto sum
. Donc, c'est vrai qu'il n'y a pas un-à-un adresse-ligne de cartographie en C/C++, vous pouvez toujours dire "donnez-moi un pointeur vers le présent code."Oups, vous avez raison. C'est gcc.
La question elle-même a toutes sortes de non-standard aspects. Il n'est que juste de donner une réponse mettant en vedette les extensions non standard.
Qui semble excellent, je cherchais quelque chose le long de ces lignes pour le compilateur gcc! vais essayer demain 😉
Notez que cela peut ne pas correspondre à ce que vous pensez qu'il fait - par exemple, gcc pourrait décider a, b, et c sont effectivement des constantes, se débarrasser de tous les d'eux, et la somme effectivement des points à l'instruction printf.
OriginalL'auteur Charlie
Visual C++ a la _ReturnAddress intrinsèque, qui peut être utilisé pour obtenir quelques infos ici.
Par exemple:
Qui vous donnera une adresse à proximité de l'expression que vous cherchez. Dans le cas de certaines optimisations, comme la queue de pliage, ce ne sera pas fiable.
OriginalL'auteur Michael
Testé dans Visual Studio 2008:
De crédit à cette question.
Ne serait-il pas mieux, juste pour le mettre dans une maison locale, puis les charger sur l'étiquette de l'adresse dans l'immédiat, MOV? par exemple: _here: mov eax, _here (saut de ligne) mov [addr], eax
Je pense que l'utilisation d'un label comme que vous ne pouvez obtenir un décalage, pas l'adresse
OriginalL'auteur RichieHindle
Voici une esquisse d'une approche alternative:
Supposons que vous n'avez pas dépouillé les symboles de débogage, et, en particulier, vous avez le numéro de ligne de la table d'adresses qu'une source de niveau de débogage symbolique des besoins afin de mettre en œuvre des choses comme seule étape en ligne de source, définissez un point d'arrêt à une ligne de source, et ainsi de suite.
La plupart des chaînes de l'utilisation raisonnablement bien documentés de débogage de formats de données, et il y a souvent des bibliothèques d'assistance qui mettent en œuvre la plupart des détails.
Étant donné que l'aide de la macro préprocesseur
__LINE__
qui renvoie le numéro de ligne en cours, il devrait être possible d'écrire une fonction qui recherche l'adresse de n'importe quelle source ligne.Avantages sont qu'aucun assemblage n'est requis, la portabilité peut être obtenue en appelant sur une plate-forme spécifique des informations de débogage de bibliothèques, et il n'est pas nécessaire de manipuler directement la pile ou d'utiliser des trucs qui cassent le PROCESSEUR pipeline.
Un gros inconvénient, c'est qu'il sera plus lent que n'importe quelle approche basée sur directement la lecture du compteur de programme.
OriginalL'auteur RBerteig
Pour x86:
OriginalL'auteur Unknown
Je ne connais pas les détails, mais il devrait y avoir une façon de faire un appel à une fonction qui peut ensuite analyser le rendement de la pile l'adresse de l'appelant, puis copie et d'impression.
OriginalL'auteur Will Hartung
À l'aide de gcc sur i386 ou x86-64:
Noter qu'en raison de la présence sur les optimisations du compilateur, la position apparente de l'expression pourrait ne pas correspondre à sa position dans la source d'origine.
L'avantage de cette méthode par rapport à l' &&foo étiquette méthode est qu'elle ne change pas le contrôle de flux graphique de la fonction. Il également ne pas briser le retour prédicteur de l'unité comme les approches utilisant l'appel 🙂
D'autre part, il est très dépendants de l'architecture... et parce qu'il ne veut pas perturber le CFG, il n'y a aucune garantie que le saut à l'adresse en question aurait plus de sens.
Jamais l'esprit, je pensais à
asm volatile
.OriginalL'auteur bdonlan
Si le compilateur est tout bon cet ajout se passe dans les registres et ne sont jamais stockées dans la mémoire, au moins pas dans le sens que vous pensez. En fait un bon compilateur verrez que votre programme ne fait rien, manipuler des valeurs à l'intérieur d'une fonction, mais jamais l'envoi de ces valeurs n'importe où en dehors de la fonction peut entraîner aucun code.
Si vous étiez à:
c = a+b;
printf("%u\n",c);
Puis un bon compilateur ne stocker que la valeur de C à la mémoire, elle va rester dans les registres, même si cela dépend du processeur. Si, par exemple, les compilateurs pour que l'utilisation du processeur de la pile pour passer des variables, des fonctions, puis la valeur de c sera calculée à l'aide de registres (un bon compilateur va voir que C est toujours 11 et juste de l'attribuer) et la valeur sera mis sur la pile tout en étant envoyé à la fonction printf. Naturellement, la fonction printf peut bien avoir besoin de stockage temporaire dans la mémoire en raison de sa complexité (ne fit tout ce qu'il doit faire dans les registres).
Où je suis en tête est qu'il n'y a pas de réponse à votre question. Il est fortement dépendant du processeur, compilateur, etc. Il n'y a pas de réponse générique. Je me demande de quoi la racine de la question est, si vous espériez de la sonde avec un débogueur, alors ce n'est pas la question à se poser.
Ligne de fond, démonter votre programme et de le regarder, pour que compiler ce jour-là avec ces paramètres, vous serez en mesure de voir où le compilateur a placé des valeurs intermédiaires. Même si le compilateur attribue un emplacement de mémoire pour la variable, qui ne signifie pas que le programme ne sera jamais stocker la variable à cet endroit. Il repose sur des optimisations.
OriginalL'auteur old_timer