Comment marche le C

Comment marche le C - C - Programmation

Marsh Posté le 04-12-2004 à 11:01:17    

Salut a tous,
j'ai un projet ambitieux a vous soumettre...
J'aimerais comprendre le fonctionnement du C plus en profondeur; malheureusement je ne sais pas ou chercher ni par ou commencer.
Pour etre plus clair je voudrais savoir comment fonctionne un compilateur C/C++, en savoir plus sur les fonction que j'utilise sans comprendre. Par exemple fprintf(), printf() et cprintf() fournisennt a peu pres le meme resultat mais y'a une histoire selon laquelle fprintf utilise le systeme de fichier du C, cprintf agit a un niveau plus bas ,bref j'ai pas tout compris.j'aimerais voir comment le compilateur travaille dans le detail et si possible avoir des equivalences en ASM pour savoir exactement ce qui se passe.
 
J'espere que c'est clair, pas trops hors sujet et que vous me repondiez evidemment.MERCI

Reply

Marsh Posté le 04-12-2004 à 11:01:17   

Reply

Marsh Posté le 04-12-2004 à 11:14:49    

Bah y a 2 trucs:
- d'une part comprendre le fonctionnement supposé des fonctions. La différence entre la console et stdout par exemple.
- d'autre part voir comment sont implémentés certaines fonctions.
 
A priori, c'est plus la partie 1 qu'il te faut, et pour ça, il suffit de lire les docs. Pour ce qui est de la deuxième partie, tu peux regarder les sources de n'importe quelle libraire standard (Microsoft fournit les siennes, GNU aussi, pareil pour OpenWatcom, qui risque de plus correspondre à l'environnement dans lequel tu travailles).
 
Un dernier truc: cprintf n'est pas standard, et n'est plus trop utilisé de nos jours.

Reply

Marsh Posté le 04-12-2004 à 11:23:07    

merci lam's
heu.. et puis
....c'est quoi la difference entre stdout et la console?
....ou je peux trouver ces docs
 

Reply

Marsh Posté le 04-12-2004 à 11:31:38    

http://forum.hardware.fr/hardwaref [...] 9954-1.htm
 
La console, c'est l'écran (toujours, ou presque).
 
stdout, par défaut c'est l'écran, mais ça peut être redirigé vers un fichier, un pipe, un autre processus, etc.
 
Exemple, si je tape ça:
   toto.exe | sort > toto.txt
 
Le stdout de toto.exe ira directement dans le stdin du programme sort. Et le stdout du programme sort ira directement dans le fichier toto.txt. Alors que l'utilisation d'un affichage sur console permettrait d'afficher des trucs à l'écran, même en cas de redirection.

Reply

Marsh Posté le 04-12-2004 à 12:35:43    

maerlin666 a écrit :

J'aimerais comprendre le fonctionnement du C plus en profondeur; malheureusement je ne sais pas ou chercher ni par ou commencer.


 
Le C est un langage de programmation normalisé. C'est à dire qu'il est spécifié par un document de portée internationale (ISO)
 

  • C90 : ISO/IEC 9899:1990
  • C99 : ISO/IEC 9899:1999


La version la plus largement répandue est C90. C99 commence à être implémentée par certains compilateur comme gcc 3.x
 
Un tel document est assez complexe. Pour simplifier, il décrit (syntaxe, sémantique) les mots clés, les instructions, les types, les valeurs minimales garanties, les structures de code, les fonctions de la bibliothèque standard avec leurs interfaces et leurs comportements.
 

Citation :


Pour etre plus clair je voudrais savoir comment fonctionne un compilateur C/C++,  


Il n'y a pas de C/C++. Il y a C et il y a C++. Ce sont des langages différents (avec des forums différents :-) )
 
Si on s'en tient à un compilateur C, c'est un programme qui lit un fichier texte contenant un programme source écrit en C. Plusieurs opérations sont réalisées:
 

  • analyse syntaxique
  • analyse sémantique
  • traduction en code machine
  • création du fichier 'objet' (pour faire simple, code machine + liste des labels non résolus)


On utilise ensuite un éditeur de lien (linker) qui rassemble les fichier objets, ajoute la ou les bibliothèques manquantes, et fabrique le fichier 'exécutable'.

Citation :


en savoir plus sur les fonction que j'utilise sans comprendre.  


Pour ça, je recommande un bon livre comme le Kernighan & Ritchie édition 2 (C90).  
 
http://www.eyrolles.com/Informatiq [...] 100051168/
 
A ma connaissance, il est en réédition. En cas de difficulté, essayer les bibliothèques ou l'occasion...

Citation :


Par exemple fprintf(), printf() et cprintf() fournisennt a peu pres le meme resultat mais y'a une histoire selon laquelle fprintf utilise le systeme de fichier du C, cprintf agit a un niveau plus bas ,bref j'ai pas tout compris.j'aimerais voir comment le compilateur travaille dans le detail et si possible avoir des equivalences en ASM pour savoir exactement ce qui se passe.


Ca, ça dépend totalement du compilateur. Même sur PC sous DOS/Windows le code produit par Borland C 3.1 (x86 mode réel) sera différent du code produit par Dev-C++ (386 mode protégé).
 
Le debugger permet parfois de visualiser une ligne de C avec sa traduction en assembleur correspondante... C'est instructif pour se fixer les idées, mais ce n'est pas essentiel...


Message édité par Emmanuel Delahaye le 04-12-2004 à 12:41:18

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 04-12-2004 à 12:53:13    

Tu peux préciser le fonctionnement d'un linker ? (Surtout lors d'une liaison à une bibliothèque)

Reply

Marsh Posté le 04-12-2004 à 13:22:29    

Il existe des livres sur les compilateurs. Le domaine général qui t'intéresse est la théorie du langage (attention si tu as du mal avec les concepts de base ca va pas être facile)

Reply

Marsh Posté le 04-12-2004 à 13:23:31    

kfman a écrit :

Tu peux préciser le fonctionnement d'un linker ? (Surtout lors d'une liaison à une bibliothèque)


Le principe de base repose sur la compilation séparée. Un module est compilé, tout ce qui est traduisible est traduit, ce qui ne l'est pas (adresse d'une fonction ou d'une variable externe), est réservé, et une table des adresses inconnues est fournie :
 
Par exemple (théorique)


list of extern labels
type label       offset size
code 'printf'    0x1234    4
code 'printf'    0x3456    4
code 'exit'      0x5678    4


D'aure part, un module compilé doit avoir au moins un point d'entrée public (exportable). Celui-ci est indiqué dans la table des labels publics


list of public labels
type label       offset size
code 'main'      0x0012    4


De même, pour une bibliothèque:


list of public labels
type label       offset size
code 'printf'    0x4568    4
code 'exit'      0x2334    4
data 'errno'     0x6366    2


etc.
Le linker utilise ces tables pour résoudre les liens manquand, c'est à dire mettre la bonne valeur d'adresses dans les parties où celle-ci était inconnue (labels non résolus).
 
Les détails réels peuvent être étudiés en cherchant des informations sur le format COFF.


Message édité par Emmanuel Delahaye le 04-12-2004 à 13:47:20

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 04-12-2004 à 13:37:03    

Tu peux regardes les transparents  
http://lampwww.epfl.ch/courses/compilation01/#slides

Reply

Marsh Posté le 04-12-2004 à 13:44:04    

Thx à vous 2... Je reviendrais peut-être vers vous...
 
EDIT: c koi l'équivalent avec Windows ?
Vous connaissez des bouquins là dessus ?


Message édité par kfman le 04-12-2004 à 14:09:52
Reply

Marsh Posté le 04-12-2004 à 13:44:04   

Reply

Marsh Posté le 04-12-2004 à 20:25:02    

wow merci pour vos reponses...
Voila ce que j'en retient:
le compilateur se borne a traduire du C en langage machine, la ou il trouve une reference exterieure au programme il met une   annotation dans une table et passe le relais au lieur.
C'est bien ca?
Pour prendre un exemple printf sera remplace par une adresse pointant sur le code de la fonction, non?
Ou alors le code de la fonction est il intégré par le linker a l'executable?
Comment printf est elle chargée en memoire...
 
Je regarde en ce moment meme les liens donnés  
PS:Wow! Certains de ceux qui ont repondu ont meme contribué a leur redaction
 
 

Reply

Marsh Posté le 04-12-2004 à 20:30:40    

J'ai trouvé ça: http://www.microsoft.com/whdc/syst [...] ECOFF.mspx
 
*EDIT*
 
D'après ce que j'ai compris en cherchant un peu:
 
Si la librairie est statique, je pense que le code est inclu.
Si elle est dynamique, le code sert à "aller chercher" la fonction.


Message édité par kfman le 04-12-2004 à 20:32:35
Reply

Marsh Posté le 04-12-2004 à 20:39:44    

ok merci kfman
donc si la librairie est statique ca veut dire quoi, qu'elle n'est pas compilée, c'est le cas des librairies fournies par le compilateurs donc printf est inclue?
Librairies dynamyque c'est les dll, pour appeler des APIs?
 
J'ai peut etre dit des enormités.
Pardonnez moi dans ce cas.

Reply

Marsh Posté le 04-12-2004 à 20:43:19    

Le lien, c'est un doc sur la structure des fichiers executables et objets.
C'est costaud comme truc
Je comprend pas grand chose

Reply

Marsh Posté le 04-12-2004 à 22:28:13    

Y'a ça aussi: http://www.freenix.fr/unix/linux/H [...] WTO-6.html
http://www.freenix.fr/unix/linux/H [...] html#ss7.1
 
Et plus généralement: http://www.freenix.fr/unix/linux/H [...] .html#toc6
 
Sinon pour comprendre les détails de plus bas niveau, il faut lire des bouquins sur l'architecture PC et les systèmes d'exploitations.
 
Pour les systèmes, je te conseille le livre d'Andrew Tanenbaum. Une bible...


Message édité par kfman le 04-12-2004 à 22:38:53
Reply

Marsh Posté le 04-12-2004 à 23:07:06    

Si une librairie est linkée statiquement, le code des fonctions utilisées par ton programme sont recopiées dans ton exécutable. Si tu te link statiquement avec la libc par exemple, un appel à printf() sera simplement une instruction de branchement vers la fonction printf().
 
Si une librairie est linkée dynamiquement, le code des fonctions utilisée par ton programme n'est PAS recopié dans ton exécutable. Quand tu lances ton programme, les librairies avec lesquelles il est linké dynamiquement sont chargées en mémoire si elle n'y sont pas déja. Puis le loader met à jour une table dans ton exécutable (la "TOC" ), qui donne pour chaque fontion externe son adresse en mémoire. Un appel à printf par exemple sera remplacé par un branchement vers un morceau de code ("glue code" ) généré par le compilateur. Ce morceau de code va simplement chercher l'adresse en mémoire dans la TOC et saute à cette adresse.


Message édité par matafan le 04-12-2004 à 23:08:36
Reply

Marsh Posté le 04-12-2004 à 23:18:52    

Ceci est encore de haut niveau et "pratique".  
La théorie des langages apporte des réponses plus génériques sur le fonctionnement global des compilateurs. Apres la facon dont s'est implémenté ca peut différer

Reply

Marsh Posté le 05-12-2004 à 10:24:19    

maerlin666 a écrit :


le compilateur se borne a traduire du C en langage machine, la ou il trouve une reference exterieure au programme il met une   annotation dans une table et passe le relais au lieur.


Oui. La table est ajoutée (généralement en tête) dans le fichier résultant de la compilation.

Citation :


C'est bien ca?
Pour prendre un exemple printf sera remplace par une adresse pointant sur le code de la fonction, non?


Vu du code machine, une fonction est une adresse qui sert de paramètre à une instruction d'appel de fonction (CALL, JSR, etc.) Par exemple, en 16-bit, la valeur de l'adresse esr remplacée par 0000, et supposons que l'Op-Code de call est 1234.  
 
(j'ai fait abstraction du paramètre pour simplifier)


  printf(xxx)   C
  CALL printf   ASM
  12 34 00 00   Code machine


Lorsque le linker va ajouter le code de la bibliothèque à l'exécutable, il va calculer l'adresse du printf() dans l'executable (par exemple 5678). Le code sera alors modifié en


  printf(xxx)   C
  call printf   ASM
  12 34 56 78   Code machine


c'est maintenent du code exécutable.

Citation :


Ou alors le code de la fonction est il intégré par le linker a l'executable?


Oui, avec les bibliothèques statiques, le code de printf (et tout ce qui va avec) est integré à l'exécutable. Ce dernier est autonome. Il en est différement avec les bibliothèques partagées (.dll, .so etc.). Là, on n'intègre que le petit bout de code qui permet de charger la bibliothèque partagée à l'exécution, et de faire l'interface entre l'appel de fonction et la fonction chargée (son adresse réelle n'étant connue qu'à l'exécution, on passe forcément par une variable de type pointeur de fonction).
 
On gagne en réduction de la taille de l'exécutable, et en optimisation de la mémoire : une seule instance d'une bibliothèque partagée correctement réalisée suffit à un nombre théoriquement infini d'applications utilisant les mêmes fonctions.
 
Autre avantage, une mise à jour de la bibliothèque permet de corriger des bugs dans toutes les applications concernées sans recompilation de celle-ci.

Citation :


Comment printf est elle chargée en memoire...


Quand elle est integrée à l'application, elle est chargée en même temps que celle-ci par le 'loader'.


Message édité par Emmanuel Delahaye le 05-12-2004 à 10:26:55

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 05-12-2004 à 10:43:00    

kfman a écrit :

Thx à vous 2... Je reviendrais peut-être vers vous...
 
EDIT: c koi l'équivalent avec Windows ?
Vous connaissez des bouquins là dessus ?


 
A ma connaissance, il n'existe qu'un bouquin, "Linkers and loaders", écrit par John Levine (le modo de comp.compilers).
 
Tu peux trouver le manuscrit du bouquin ici : http://www.iecc.com/linker/


Message édité par printf le 05-12-2004 à 10:45:00

---------------
Un matin je me lèverai et il fera beau.
Reply

Marsh Posté le 05-12-2004 à 10:57:08    

Merci, je vais jeter un oeil...
 
Top niveau ton lien, mon cher printf... :o


Message édité par kfman le 05-12-2004 à 11:10:59
Reply

Marsh Posté le 07-12-2004 à 18:52:20    

En effet le lien est super meme si en anglais...
Je l'ai parcouru en partie et j'ai deja decouvert plusieurs truc tres interessant
 
pour le chargement ca a l'air plus comliqué pour static et dynamic que prevu...
j'y retourne

Reply

Marsh Posté le 09-12-2004 à 20:33:11    

Re,
grace a vos reponses dans ce post j'arrive maintenant a me faire une idée plus precise du processus qui aboutit a la creation de code executable par la machines.
Je continue mes recherches en me basant sur les liens et informations que vous m'avez fournis.
J'aimerais savoir ou il est possible de trouver le source de foncttions telles que printf ou d'autres qui sont inclues dans les executables.
J'aimerais aussi savoir d'ou sont chargées les librairies dynamiques (elles doivent etre presentent sur l'ordinateur
qui execute le programme et celui ci doit etre capable de determiner ou les trouver.)
Je crois que sous unix une variable est definie a cet usage,
qu'en est il sous windoz.
 
Encore une fois merci pour vos reponses  
 

Reply

Marsh Posté le 09-12-2004 à 22:33:45    

Printf et autres : http://www.gnu.org/software/libc/libc.html
 
Les libraries dynamiques peuvent êtres chargées depuis n'importe ou avec Linux à condition d'être dans LD_LIBRARY_PATH.
 
Sous windows je sais pas.

Reply

Marsh Posté le 09-12-2004 à 22:46:27    

kfman a écrit :

Merci, je vais jeter un oeil...
 
Top niveau ton lien, mon cher printf... :o


 
Ben tiens :D
 
 
Pour ceux que les parsers intéressent y'a aussi : http://www.cs.vu.nl/~dick/PTAPG.html (écrit par un grand nom de la compilation, qui plus est collègue de Tanenbaum :o)
 
Tiens, c'est aussi l'inventeur de CVS :D


Message édité par printf le 09-12-2004 à 22:49:07

---------------
Un matin je me lèverai et il fera beau.
Reply

Marsh Posté le 10-12-2004 à 16:38:56    

Le sujet est vaste et il a pas mal de zone sur lesquelles j'aimerais en savoir plus...
 
fafounet precise que les librairies dynamiques sont chargées grace a une variable sous linux(LD_LIBRARY_PATH)...  
Sous windows?
 
Comment se procurer le code des fonctions C ?
 
A quoi sert la fonction main outre a indiquer le debut du code?
 
Quelle est la difference entre un pointeur int, char, etc.?
Je veux dire par la comment le programme determine le nombre d'octets concernés.
 
Heu voila ...
 
 

Reply

Marsh Posté le 10-12-2004 à 16:50:40    

ben le main n'a pas beaucoup plus d'utilité que ça, il sert aussi à récupérer las paramètres passés en ligne de commande.
 
maintenant quel est la différence entre un pointeur int et char ? ben c'est trés simple, une pointeur c'est une adresse mémoire mais tu va dire pourquoi doit on lui déclarer un type : char*, int* ... une adresse c'est toujours pareil !
 
et bien ça joue son rôle pour l'arithmétique des pointeurs en effet imaginons
char *a = 0x00000000;//une adresse quelconque
a++;
et bien au aura a=0x00000001;
 
maintenant avec des int*
 
int *a = 0x00000000;
a++;
-> a=0x00000004  ---> sizeof(int) on aura bien décalé d'un entier mémoire
 
c'est à ça que ça sert. Cela correspond à BYTE PTR et WORD PTR en assembleur


Message édité par spokup le 10-12-2004 à 16:51:41
Reply

Marsh Posté le 10-12-2004 à 16:53:30    

Ah merci!
Je crois que je l'avais vu dans un bouquin sur l'assembleur mais je m'en rapellais plus. merci en tout cas...

Reply

Marsh Posté le 10-12-2004 à 17:08:05    

Ah oui c'est pas tout:
 
char c'est un octet  
int c'est deux ou quatre octets
 
si je mets 1 en char a partir de l'adresse 0 ca fait: 01
si je mets 1 en int  a partir de l'adresse 0 ca fait: 0001
 
si ensuite je viens reprendre mon char ou mon int le nombre d'octet a prendre sera different.
comment determine on le nombre d'octet concerné grace au pointeur

Reply

Marsh Posté le 10-12-2004 à 17:11:16    

Peut etre que ca a un rapport avec le fait que le char soit placé dans AL et le int dans AX...
ou surement que c'est pas ca...

Reply

Marsh Posté le 10-12-2004 à 17:17:51    

un pointeur c'est une adresse 01 et 00001 c'est exactement la meme adresse !
 
ensuite ce la pointe toujours sur un octet en particulier, il ne sait en aucun cas comment est la zone mémoire qui suis.
 
si tu allou de l'espace comme ça
char *p = malloc(16);
 
et que tu fait référence à
p[37] et ben ce sera gros cacaprout !

Reply

Marsh Posté le 10-12-2004 à 17:47:08    

maerlin666 a écrit :


A quoi sert la fonction main outre a indiquer le debut du code?


On ne peut pas écrire un programme C conforme sans une fonction main(). Celle-ci sert de point d'entrée, et la terminaison de cette fonction constitue la fin du programme. Elle sert aussi à récuperer les paramètres de la ligne de commande, si on utilise la forme

Code :
  1. int main (int argc, char **args)
  2. {
  3.    /* ... */
  4.    return 0;
  5. }


Les détails sont dans ton livre de C.

Citation :


Quelle est la difference entre un pointeur int, char, etc.?
Je veux dire par la comment le programme determine le nombre d'octets concernés.


En C, on ne parle pas d'octets, mais de bytes (le terme français officiel est 'multiplet', mais je ne l'utilise pas. Trop laid...).  
 
En effet, un char fait 'au moins' 8-bit et non 'exactement' 8-bit, ce qui rend le terme 'octet' (qui veux dire 'exactement 8-bit') inapproprié.
 
Un pointeur est une variable typée qui contient une adresse. Le type (sauf void) indique une valeur utilisée par l'arithmétique des pointeurs du langage C qui permet par exemple d'adresser un élément dans un tableau. La valeur (taille du type) dépend de l'implémentation.


Message édité par Emmanuel Delahaye le 10-12-2004 à 21:52:48

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 10-12-2004 à 20:44:41    

ok, pour la terminologie je suis pas tres au point donc  
je me suis mal exprimé
par 01 j'entend un byte de donné ( char en general
par 0001           un word (int en general non?
 
ce ne sont pas des adresses mais les valeures des variables qui ont des longuers differentes  
 
Le pointeur c'est l'adresse 00000000 (char*, int*
Je voulais savoir comment un pointeur determinait la taille de la variable memoire a recuperer
je pense que ca depend de l'emplacement de destination
 
par exemple
 
a byte 1
b word 1
mov ax,b
mov a,ax impossible (mov a,al)
 
pas de probleme tant que b<256
sinon on aura une troncature mais ca marche
 
par contre  
 
int* truc
char* bidule
 
truc*=bidule* ne marche pas
la taille de truc est trop grande
le compilateur empeche la compilation
 
...
je crois qu'en fait je viens de comprendre,voila
 

Reply

Marsh Posté le 10-12-2004 à 20:51:04    

C'est justement le type de pointeur qui determine la "taille de la variable memoire a recuperer". Si tu dereference un int * il lira sizeof (int) bytes (probablement 4 sur ta machine). Si tu derefencre un long long * il lira sizeof (long long) bytes (probablement 8 sur ta machine).
 
Ce qui fait que tu ne peux pas derefencer un void *. Il faut le caster d'abord : "int a = *((int *)void_ptr);".
 
C'est quoi ce "truc*=bidule*" ? Avec ca si le compilo te jette ca n'a rien a voir avec le type des pointeurs :D


Message édité par matafan le 10-12-2004 à 21:02:35
Reply

Marsh Posté le 10-12-2004 à 21:22:53    

voila c'est ca que je cherche a savoir
c'est le type de poinnteur qui determine ...
mais un pointeur c'est juste une adresse de depart non?
il n'y a aucune difference entre un pointeur int* et char* physiquement , si?
 
et je voulais dire *truc=*bidule

Reply

Marsh Posté le 10-12-2004 à 21:49:34    

Tout a fait. Mais le compilateur, lui, connait aussi le type du pointeur. A partir de la il genere les load/store (ou la suite d'instructions) qui vont bien pour travailler sur 8, 16, 32 ou 64 bits.

Reply

Marsh Posté le 10-12-2004 à 21:58:20    

maerlin666 a écrit :

voila c'est ca que je cherche a savoir
c'est le type de poinnteur qui determine ...
mais un pointeur c'est juste une adresse de depart non?
il n'y a aucune difference entre un pointeur int* et char* physiquement , si?
 
et je voulais dire *truc=*bidule


Un pointeur, c'est une variable qui contient une adresse.
Une adresse, c'est un pointeur constant.
 
http://mapage.noos.fr/emdel/notes.htm#pointeurs


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 10-12-2004 à 22:18:05    

certes,  
ce que je dis c'est qu'il n'y a pas de difference entre un pointeur de type int* et un de type char* puisque les deux contiennent une adresse.
Partant de la si je fais  
int* p;
*p=1;
les emplacements memoire a partir de l'adresse contenue dans p ressembleront a ca: 0x00000001
si je fais
char* pt;
*pt=1;
les emplacement .... dans pt ressambleront a ca: 0x0001
pourtant physiquement int* p revient a char* pt
par exemple ils contiennent tous les deux l'adresse 0x00000000
alors comment expliquer cette difference?

Reply

Marsh Posté le 10-12-2004 à 22:42:52    

Mais c'est exactement je t'ai explique... Le compilo connait le type du pointeur, donc il genere les instructions qui vont bien pour lire/ecrire la quantite qu'il faut. Par exemple (bon desole c'est sur architecture Power, j'ai que ca sous la main) :

Code :
  1. int
  2. main()
  3. {
  4.         int *int_ptr;
  5.         char *char_ptr;
  6.         *int_ptr = 1;
  7.         *char_ptr = 1;
  8.         return 0;
  9. }


Ca donne (j'ai mis quelques commentaires en, disons, pseudo-C) :

$ dbx ./test
Type 'help' for help.
reading symbolic information ...warning: no source compiled with -g
 
(dbx) listi main
0x10000330 (main)      9421ffb0       stwu   r1,-80(r1)
0x10000334 (main+0x4)  80810040        lwz   r4,0x40(r1)  # r4 = int_ptr;
0x10000338 (main+0x8)  38600001         li   r3,0x1       # r3 = 1;
0x1000033c (main+0xc)  90640000        stw   r3,0x0(r4)   # *r4 = r3;
0x10000340 (main+0x10) 80810044        lwz   r4,0x44(r1)  # r4 = char_ptr;
0x10000344 (main+0x14) 98640000        stb   r3,0x0(r4)   # *r4 = r3;
0x10000348 (main+0x18) 38600000         li   r3,0x0       # r3 = 0;
0x1000034c (main+0x1c) 38210050       addi   r1,0x50(r1)
0x10000350 (main+0x20) 4e800020        blr                # return(r3);
0x10000354 (main+0x24) 00000000       Invalid opcode.
(dbx)  


 
Pour info r3 a r31 sont des registres generaux 32 bits. r1 et le pointeur de pile. Les fonctions retournent leur valeurs dans le registre r3. Les deux instructions non commentees servent a reserver/liberer la stack frame.
 
Tu vois que la premiere affectation utilise un stw (store word), et ecrit donc 1 sur 32 bits a l'adresse int_ptr. La deuxieme affectation utilise un stb (store byte), et ecrit donc 1 sur 8 bits a l'adresse char_ptr.


Message édité par matafan le 10-12-2004 à 22:53:00
Reply

Marsh Posté le 10-12-2004 à 22:45:32    

maerlin666 a écrit :

ce que je dis c'est qu'il n'y a pas de difference entre un pointeur de type int* et un de type char* puisque les deux contiennent une adresse.


Admettons.

Citation :


Partant de la si je fais  
int* p;
*p=1;


STOP! Marche pas, 'p' n'est pas initialisé. Déréférencer un pointeur non initialisé invoque un comportement indéfini.

Citation :


les emplacements memoire a partir de l'adresse contenue dans p ressembleront a ca: 0x00000001
si je fais
char* pt;
*pt=1;


Même problème que précédemment.

Citation :


les emplacement .... dans pt ressambleront a ca: 0x0001


En admettant que pt est correcement initialisé, plutôt à ça : 0x1 sur les plateformes dont les char font 8-bit.

Citation :


 
pourtant physiquement int* p revient a char* pt
par exemple ils contiennent tous les deux l'adresse 0x00000000
alors comment expliquer cette difference?


Comme expliqué 14.000 fois, c'est le type qui fait la différence. Il renseigne le compilateur sur la façon d'accéder à la mémoire via le pointeur en question. Il sait combien de bytes il doit lire, et de combien de bytes se déplacer dans un tableau pointé par ce type de pointeur.
Et si tu lisais un livre de C comme le Kernighan & Ritchie (édition 2), où toutes ces notions élémentaires sont décrites noir sur blanc...
 
Je sais que ce livre est en ré-édition dans sa version française, mais il doit se trouver dans les bibliothèques...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 10-12-2004 à 23:19:53    

Citation :

Il sait combien de bytes il doit lire, et de combien de bytes se déplacer dans un tableau pointé par ce type de pointeur.  


la question depuis le debut est comment sait il
 
a pardon j'avais pas vu

Citation :

Tu vois que la premiere affectation utilise un stw (store word), et ecrit donc 1 sur 32 bits a l'adresse int_ptr. La deuxieme affectation utilise un stb (store byte), et ecrit donc 1 sur 8 bits a l'adresse char_ptr.


en x86 ca fait quoi parce que je connait aucun des opcode pratiquement
et ce que je ne comprend pas c'est comment il fait la difference entre un int* et un char* pour ensuite decider de faire stwd ou stb


Message édité par maerlin666 le 10-12-2004 à 23:55:40
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed