TP 18:De Processing au processeur

De Processing à C

Y-a-t-il une différence entre les instructions i = i + 1; et i++;?

Voici un programme en Processing , copiez le exécutez le et expliquez ce que vous avez observé


void setup(){

	int i = 51;
	println("Pour i = "+i+" println(i = i + 1) affiche "+(i = i + 1));
	
	i = 51;
	println("Pour i = "+i+" println(i++) affiche "+(i++));
	println(" i = "+i);
}

Le but de ce TP est de découvrir un peu comme pour les images numériques, le codage du programme, à l'intérieur de l'ordinateur

Pour cela nous allons passer par un autre langage de programmation,le C qui dispose d'utilitaires nous permettant de "voir" le codage du programme en machine

Voici le même programme mais en C


#include <stdio.h >
main(){
	
	int i = 51;
	printf("printf(i = i + 1) affiche %d\n",i=i+1);
	
	i = 51;
	printf("i = %d\n",i);
	printf("printf(i++) affiche %d\n",i++);
	printf("i = %d\n",i);
}

Nous voulons regarder à l'intérieur de la machine la différence entre ces deux instructions

  1. Ouvrir l'éditeur de texte gedit et copier le programme ci-dessus dans un nouveau fichier
  2. Sauvegarder le programme dans le répertoire principal en le nommant pgm.c
  3. Ouvrir le terminal,Aller dans le terminal , à l'ouverture du terminal vous êtes dans le répertoire principal et vous voyez à l'écran par exemple ceci:
    
    utilisateur@poste1B30:~$
    

    ce qui signifie que vous êtes dans le répertoire personnel (le ~) de l'utilisateur utilisateur sur le poste 1 de la salle B30. Le prompt $ signifie que le terminal attend une commande de votre part.

    Vous aller faire compiler ce fichier (transformer un fichier texte (utf-8) en un fichier binaire exécutable) par un compilateur en entrant la commande suivante:

    
    utilisateur@poste1B30:~$gcc -o pgm pgm.c
    

    Le compilateur va vérifier que le fichier est correctement écrit en C, et s'il y a des erreurs, il va vous aider à les corriger, puis le compilateur va transformer ce fichier texte .c en un fichier binaire

    Aller voir dans le répertoire personnel, vous devez avoir deux fichiers l'un pgm.c l'autre pgm et regarder leurs propriétés

    Essayer d'ouvrir pgm avec gedit Qu'observez vous ?.

    Essayer d'ouvrir pgm avec Jeex Qu'observez vous ?.

  4. Exécuter le programme en entrant ./pgm puis faire entrée

Utilisation de objdump

objdump est un utilitaire qui nous permettra d'avoir le code du programme pgm

Pour commencer simplement on commente tout à l'intérieur du main ()

Compilez le programme

Entrez la commande suivante qui nous permettra de désassembler le code binaire pgm

-M intel pour machine intel par défaut c'est l'affichage motorola ,-D pour disassemble


utilisateur@poste1B30:$objdump -M intel -D pgm 

Beaucoup de lignes apparaissent et pourtant nous avons l'impression que notre programme ne fait rien!

Si vous pouvez remonter tout en haut de la fenêtre (sinon aller dans Edition sélectionner Profils...faire Nouveau nommer un nouveau profil objdump et sélectionner l'onglet défilement et cocher illimité puis sélectionner objdump dans profil utilisé au lancement du terminal


pgm: file format elf32-i386

Ce qui signifie que pgm est un fichier au format extended linked file pour les processeurs de la famille intel 386 avec des registres de 32 bits

Dans la section .text: on trouve le <main>

Nous allons nous intéresser plus précisément au désassemblage du <main>

Pour cela entrer la commande suivante,qui filtre le résultat précédent en ne conservant que les 30 lignes qui suivent main>:


utilisateur@poste1B30:$objdump -M intel -D pgm |grep -A30 main.:

Si on veut conserver le résultat précédent dans un fichier texte pour l'afficher dans une page html par exemple on redirige (>) le résultat vers un fichier que l'on nomme par exemple objdump.txt


utilisateur@poste1B30:$objdump -M intel -D pgm |grep -A30 main.:> objdump.txt

Voici ce que l'on obtient si on ajoute l'instruction int i = 51; dans le main()

Retenir que :

  1. Le programme est en mémoire décomposé en opérations pour le processeur. Chaque opération occupe une ligne dans le fichier objdump
  2. Un processeur n'a qu'un nombre fini d'opérations(une centaine).
  3. Ci-dessous un micro-contrôleur arduino uno équipé d'un processeur avr d'atmel ayant un ensemble de 131 opérations
  4. Voir ici la documentation du constructeur
  5. Voir ici les opérations habituelles pour les processeurs i386
  6. Une instruction peut donner lieu à plusieurs opérations
  7. La mémoire est repérée par des adresses
  8. Une structure de la mémoire appelée PILE joue un rôle important pour les variables locales et les fonctions
  9. Chaque opération est repérée par une adresse mémoire gérée par l'unité de contrôle du processeur
  10. Chaque opération commence par un opCode puis des arguments
  11. Pour plus de lisibilité il y a le langage assembleur
  12. Par exemple à l'adresse 0x80483ba il y a c7 45 fc puis 33 00 00 00
  13. Remarquer la disposition des nombres en mémoire (little endian) 0x33 est rangé ainsi 33 00 00 00
  14. c7 est l'opCode d'un déplacement (mov) d'une valeur constante (0x33=51) au sommet de la pile (repéré par un pointeur appelé esp)

Exercice

Si...alors...

Testez


#include <stdio.h >
main(){
	
	int i = 129;
	//seuil
	if(i >= 128){
		i = 128;
	} 
}

Appel de fonction

Machine de Von Neumann

Toutes les machines(ordinateurs fixes, portables, téléphones, tablettes, micro contrôleurs...), au delà de quelques différences sont dites à architecture de Von Neumann

Voir un peu d'histoire ici