Desassembler un programme linux (en C)

Desassembler un programme linux (en C) - C - Programmation

Marsh Posté le 25-07-2017 à 12:31:37    

Bonjour
 
J'ai écrit un programme en C (sous linux) pour faire un test de vitesse d'une fonction. J'ai ensuite compilé ce programme avec gcc et l'option -O3. Il me semble que ce programme tourne "trop vite" (oui je sais c'est pas courant de se plaindre de cela). Je crains que cette vitesse innatendue soit dûe à l'optimiseur qui a trouvé que mon code ne faisait rien et donc qui a viré tout le code de test. En gros mon programme à la forme suivante:
 

Code :
  1. int main()
  2. {
  3.       uint8_t x, y, z;
  4. }

Reply

Marsh Posté le 25-07-2017 à 12:31:37   

Reply

Marsh Posté le 25-07-2017 à 14:36:52    

Ben oui ton programme ne fait rien!

 

Revenons au début: Que cherches-tu à faire exactement?


Message édité par rat de combat le 25-07-2017 à 14:44:41
Reply

Marsh Posté le 25-07-2017 à 15:20:21    

C'est clair que déclarer 3 variables non utilisées par la suite, il a pas trop de boulot à faire le compilo :/
 
Edit : du reste, comment mesures-tu que ton "programme" tourne trop vite vu qu'il ne fait rien :??:

Message cité 1 fois
Message édité par rufo le 25-07-2017 à 15:21:03

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 25-07-2017 à 18:03:23    

rufo a écrit :

Edit : du reste, comment mesures-tu que ton "programme" tourne trop vite vu qu'il ne fait rien :??:

$ time monprogramme
temps d'exécution: 0
nombre d'exécutions possibles par seconde:
***FATAL*** time has been terminated: division by zero

Pardon, je sors... :o

Reply

Marsh Posté le 25-07-2017 à 22:40:18    

Désolé, étant peu familier d'Unix, je ne connaissais pas la commande time :/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 26-07-2017 à 00:01:25    

rufo a écrit :

Désolé, étant peu familier d'Unix, je ne connaissais pas la commande time :/

Je sais pas si leonhard a utilisé cette commande et mon post c'est de la pure invention, l'affichage de time est complètement différent en vrai. C'était une blague (ou c'était censé en être une). :o


Message édité par rat de combat le 26-07-2017 à 00:01:48
Reply

Marsh Posté le 26-07-2017 à 11:37:02    

leonhard a écrit :

Bonjour
 
J'ai écrit un programme en C (sous linux) pour faire un test de vitesse d'une fonction. J'ai ensuite compilé ce programme avec gcc et l'option -O3. Il me semble que ce programme tourne "trop vite" (oui je sais c'est pas courant de se plaindre de cela). Je crains que cette vitesse innatendue soit dûe à l'optimiseur qui a trouvé que mon code ne faisait rien et donc qui a viré tout le code de test. En gros mon programme à la forme suivante:
 

Code :
  1. int main()
  2. {
  3.       uint8_t x, y, z;
  4. }



 
Désolé, j'ai eu un problème pour poster ce message, il en manque les 3/4. Le code serait plutôt du genre:
 

Code :
  1. ... les include qui vont bien
  2. uint8_t fonction (uint8_t p1, uint8_t p2) { ..... }
  3. int main()
  4. {
  5.       uint8_t x, y, z;
  6.       int counter;
  7.       x = 18; y = 36;
  8.       for (counter = 0; counter < 100000000; counter ++) {
  9.           z = fonction(x,y);
  10.       }
  11. }


 
La fonction time (que je connaissais) indique que pour 100 millions d'appel le temps d'exécution est d'environ 2.6 secondes et pour 1 milliard environ 26 secondes.
 
Entre temps j'ai "découvert" l'utilitaire gprof qui me dit que ma fonction est appelée le nombre de fois correspondant à la boucle. Mais je ne sais pas (encore) comment utiliser gprof avec l'optimisation de code -O3. Les options "-pg" et "-O3" ne semblent pas copines :D  Je continue de chercher, mais merci de votre aide et désolé pour le bruit.

Reply

Marsh Posté le 26-07-2017 à 11:41:37    

Je ne comprends quel est le pb du coup :??: Time te donne 2.6s pour 100 millions de boucles et 10 fois plus pour 1 milliard. C'est cohérent.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 26-07-2017 à 12:42:20    

Si x et y ne changent pas, l'optimiseur va le voir et n'éxécuter qu'une fois.


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 26-07-2017 à 14:39:35    

J'en doute vu que lorsqu'il multiplie x10 le nb de boucle, la durée est aussi x10.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 26-07-2017 à 14:39:35   

Reply

Marsh Posté le 26-07-2017 à 14:43:48    

rufo a écrit :

Je ne comprends quel est le pb du coup :??: Time te donne 2.6s pour 100 millions de boucles et 10 fois plus pour 1 milliard. C'est cohérent.

+1.
 
Encore une fois (@leonhard): Que cherches-tu à faire  / régler comme problème /...?

Reply

Marsh Posté le 26-07-2017 à 15:40:16    

rat de combat a écrit :

+1.
 
Encore une fois (@leonhard): Que cherches-tu à faire  / régler comme problème /...?


 
Bon je vais essayer d'expliquer clairement ce qui ne l'est pas dans ma tête. Il y a quelques temps, lors d'une discussion autour d'une bière, nous parlions d'un mécanisme de crypto que nous devons mettre en place. Un collègue me disait que pour faire les multiplications dans un corps de galois GF(2^8), il faut précalculer tous les produits possibles (256*256) et le stocker dans une table parce que ce serait trop cher (en temps) de recalculer les produits quand nous en avons besoin. Mon collègue n'a pas l'habitude de raconter des conneries, donc je n'ai pas de raison de ne pas le croire. Cependant, j'aime bien aussi voir avant de croire (*) donc je me suis dit, je vais programmer naïvement cette multiplication, faire quelques milliers de multiplication et "mesurer" le temps nécessaire. L'algorithme de la multiplication dans un corps de Galois se trouve par exemple sur Wikipedia ([url] https://en.wikipedia.org/wiki/Finite_field_arithmetic[/url]). Je me répète, je voulais une implantation naïve et claire, comme celle donnée dans cet exemple et je ne cherche pas de ruses de sioux pour optimiser des quart de pouillèmes de bits.  
 
J'ai donc copié ce code (c'est ce que fait ma "fonction" ), j'ai donné aux deux variables x et y des valeurs aléatoires différentes pour chaque appel, compilé le tout et en voiture Simone. J'ai lancé le programme avec 10'000 multiplications, mais le temps d'exécution est très (trop) proche de zéro pour avoir quoi que ce soit de significatif. Je suis monté par essais à 100 millions de multiplications, pour avoir les 2.6 secondes. Cependant je sais par expérience que souvent l'optimisateur de code de GCC (et de la plupart des compilateurs modernes d'ailleurs) est extrêment fûté et donc je me demandais s'il était capable de voir que j'appellais 100 millions de fois la fonction mais que le résultat de cette fonction (dans la variable 'z') n'était jamais utilisé et donc qu'il aurait pu simplement remplacer le contenu de la boucle par un "nop" (clin d'oeil à M. rat de combat). Le fait que  quand je multiplie le nombre de boucles par 10 cela multiplie aussi le temps d'exécution par 10 semble me faire penser que cette réduction code ne se fait pas. J'ai aussi utiliser le profilage (sans optimisation) et là le rapport de gprof dit que ma fonction est vraiment appellée 100 millions de fois. Comme je l'ai dit plus haut, je n'ai pas réussi à utiliser à la fois le profiler ET l'optimisation maximale.
 
La deuxième étape de mon test sera de créer une table à 2 dimensions avec 65'536 éléments (de 1 byte chacun) et de voir le gain en appellant simplement les éléments de la table. Mais je sais déjà que dans notre appli, il y a aura des appels bien plus gourmands en temps que cette petite multiplication. Même si le gain est de 80% (ce qui serait énorme) ça ne fera jamais que 2 secondes de gagnées pour 100 millions de multiplications ce qui doit correspondre en gros à nos besoins pour 1 jour de travail.  
 
 
 
(*) La réalité n'est qu'une hallucination provoquée par un manque d'alcool!


Message édité par leonhard le 26-07-2017 à 15:46:03
Reply

Marsh Posté le 26-07-2017 à 16:28:09    

Le C est très performant : 2s d'exécution, c'est bien trop long pour un simple "nop" :o Tu peux être sûr que ta fonction est correctement appelée.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 26-07-2017 à 16:55:44    

Complexité de l'algo linéaire, résultat de temps d’exécution linéaire, perso je ne vais pas chercher plus loin...
Mais tu peux toujours faire varier le nombre de calculs de ta fonction dans ta boucle pour voir ce qu'il en est ou même faire varier le nombre de calculs dans ta fonction.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 27-07-2017 à 08:57:35    

pour répondre à la question initiale, pour désassembler un binaire tu peux utiliser objdump.
 
Ex sur plateforme intel :


#objdump -M intel -d tonbinaire


 
Si t'es sur une architecture plus exotique, tu peux utiliser un site de ce genre : https://www.onlinedisassembler.com/static/home/

Reply

Sujets relatifs:

Leave a Replay

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