2010-12-11 41 views
1

Pour vérifier, j'ai essayé le code suivant:allocation variable dans les segments

const int i = 100; 
static int m = 90; 
const int p = 40; 
int x; 

main() 
{ 
    const int j = 40; 
    static int k = 40; 
    const int n; 

    char *p = "Rama"; 
} 

Alors s'il vous plaît dire quelle variable va quel segment que je suis la sortie suivante sur le compilateur gcc. Quand je l'ai écrit

size ./a.out 

Je suis:

text data bss dec hex filename 
865 268  12 1145 479 ./a.out 
+0

865 + 268 + 12 = 1145 = 0x479 – pmg

Répondre

1

Vous pouvez utiliser nm. Voici un exemple: test.c contient l'exemple que vous avez posté:

gcc -o test test.c 
nm -p -m test 

00001fb0 (__TEXT,__text) non-external (was a private external) dyld_stub_binding_helper 
00001fc4 (__TEXT,__text) non-external (was a private external) __dyld_func_lookup 
00002010 (__DATA,__data) non-external dyld__mach_header 
00002014 (__DATA,__data) non-external _m 
00002018 (__DATA,__data) non-external _k.1510 
0000200c (__DATA,__data) external _NXArgc 
00002008 (__DATA,__data) external _NXArgv 
00002000 (__DATA,__data) external ___progname 
00001000 (absolute) [referenced dynamically] external __mh_execute_header 
00002004 (__DATA,__data) external _environ 
00001ff0 (__TEXT,__literal4) external _i 
00001fd2 (__TEXT,__text) external _main 
00001ff4 (__TEXT,__literal4) external _p 
00002038 (__DATA,__common) external _x 
00001f70 (__TEXT,__text) external start 
     (undefined [lazy bound]) external _exit (from libSystem) 

Vous pouvez utiliser la technique décrite here pour contrôler le segment des variables vont. (Dans MS VC, vous pouvez utiliser #pragme data_seg("segname")).

+0

ok merci khachik – codeomnitrix

1

variables et des choses aller où votre compilateur veut les mettre. Vous pouvez avoir un certain choix sur la façon dont le compilateur se comporte à travers les options.

Vous aimeriez visiter les liens suivants:

http://en.wikipedia.org/wiki/A.out

http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

+0

hé j'ai visité ces liens mais je n'ai rien trouvé qui me convienne. En fait, je veux savoir ce que var va à quel segment. et que signifie la déc et l'hex. Merci pour votre réponse – codeomnitrix

+0

hex et dec sont la somme de la taille du test et des données. un seul est décimal et un est hexadécimal. (1145) 10 = (479) 16 – BlackBear

0

Je pense que tu deviens confus entre le sens de static et const ce qui est compréhensible que vous (et moi!) oublient souvent leur signification une fois que vous avez lu la théorie une fois.

1) Premièrement, const. Ce que signifie const, c'est que nous ne changerons pas la valeur de la variable par cette «référence». Ceci est vraiment utile pour les arguments de la fonction, en particulier lorsque vous utilisez des pointeurs, afin de ne pas éditer les valeurs que vous n'aviez pas l'intention de faire. Par exemple, arbitrairement:

void add(int* result, const int* a, const int* b) 

Cette déclaration signifie que si nous accidentellement dactylographié a = result + b; le compilateur doit se plaindre et refuser de compiler. Dans ce cas, nous avons nommé les variables de telle sorte que nous ne devrions pas les écraser même par accident, mais dans des scénarios plus complexes, cela peut arriver.

Comme l'indique pmg, cela ne signifie pas que la valeur ne changera pas; cela signifie simplement que lorsque nous parlons de cette version de cette adresse/valeur, nous ne la changerons pas. Mon point ici est qu'il est utile de protéger les arguments que vous n'avez pas l'intention de changer au cas où vous tenteriez accidentellement de les changer. Si vous voulez un préprocesseur à valeur fixe, vous pouvez souvent l'utiliser, par exemple. #define TRUE 1.

2) maintenant static. Statique signifie "non visible en dehors de cette unité de compilation". C'est comme, et je souligne comme, mais pas équivalent à, la notion de privé dans les classes, mais dans ce cas, nous parlons de l'ensemble du fichier C. Donc, si nous sommes dans le fichier helloworld.c et en haut vous écrivez:

static int x = 10; 

Vous ne pouvez pas utiliser alors cette version de x en helloworld2.c.

3) Pendant que nous y sommes, nous pourrions aussi bien faire l'autre mot inline. inline est en quelque sorte une façon plus agréable de faire des macros à mon avis et signifie "compilateur, vous devriez vraiment mettre le code résultant de là où vous l'appelez, plutôt que de nous coûter un appel de fonction". L'optimisation des compilateurs pourrait le faire de toute façon, mais cela agit comme une instruction explicite à intégrer si possible. En résumé, ces fonctionnalités contrôlent toutes les parties du langage et non l'endroit où la variable est placée dans les différents segments de l'exécutable. Comme le dit pmg, le compilateur peut faire ce qu'il veut.

Si vous voulez avoir une idée de ce que le compilateur a fait, utilisez gcc -S. Cela vous donne la sortie en langage assembleur de gcc qui sera au format AT & T. Essayez ceci avec différents gcc -Oxx=0,1,2,3 drapeaux pour avoir une idée du fonctionnement de l'optimisation.

Enfin, il est intéressant de noter qu'en fait a.out est simplement un nom; votre noyau moderne est probablement compilé sans support pour les binaires a.out. Je pense que c'est la question que vous essayiez vraiment de poser.

+0

Correctement vrai. Je vais éditer. –

1

Normalement, les données non initialisées iraient dans BSS et les données initialisées dans DATA (voir here).

Mais ISO C ne prescrit pas ce genre de chose, c'est tout à fait un problème de mise en œuvre. Le dec et hex dans votre question sont les totaux des trois autres en décimal et hexadécimal respectivement:

865 + 268 + 12 = 1145 = 0x479 

Si vous voulez vraiment savoir, il existe différents outils que vous pouvez utiliser, tels que gcc -S lors de la compilation pour obtenir le sortie du langage d'assemblage, ou nm et ses frères pour regarder à l'intérieur des fichiers objet.

+0

kk merci paxdiablo – codeomnitrix