CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Explication bytecode Java

pseuuuuuuuuuudo
pseuuuuuuuuuudo
Niveau 10
09 janvier 2014 à 12:57:21

Bonjour,

J'aimerais bien quelques explications sur le résultat d'une compilation, car j'ai du mal à me représenter le fonctionnement de certaines instructions basiques du bytecode Java.

Voici un programme simple : http://pastebin.com/hBLh1M13
Voici le bytecode correspondant (compilateur Java 7, mais ça doit pas changer grand chose pour un code aussi simple) : http://pastebin.com/KX0WfMAw

J'ai un peu de mal avec le bytecode de la méthode "method()".

0: iload_1 // Je suppose qu'on ajoute l'entier passé en paramètre au sommet de la pile

1: iconst_5 // On ajoute la constante 5 au sommet de la pile

2: iadd // On ajoute les deux entiers au sommet de la pile. Je suppose que le résultat est placé au sommet de la pile ?

3: istore_2 // On stocke la valeur au sommet de la pile dans une variable nommée 2

4: iload_2 // On charge le contenu de la variable 2 au sommet de la pile

5: ireturn // Et on retourne la valeur au sommet de la pile

En fait je comprends pas le pourquoi des opérations 3 et 4. Je pense que c'est moi qui interprète mal leur fonction, mais je vois pas pourquoi on dépile dans la variable 2 pour ensuite réempiler cette valeur :doute:

Pourquoi on ne fait pas le ireturn directement après le iadd ?

pseuuuuuuuuuudo
pseuuuuuuuuuudo
Niveau 10
09 janvier 2014 à 13:03:57

Et aussi une question qui me vient tant que j'y suis :

Après les instructions 0 et 1, ma pile doit ressembler à ça (on suppose que je passe 3 en paramètre de ma méthode) :

| 5 |
| 3 |
¯¯

Est-ce qu'après le iadd elle ressemble à ça :

| 8 |
| 5 |
| 3 |
¯¯
ou à ça

| 8 |
¯¯
? C'est à dire est-ce que les deux valeurs qui ont été ajoutées sont dépilées ou non ?

Bunyan
Bunyan
Niveau 17
09 janvier 2014 à 14:08:07

D'instinct je dirai plutôt le second.

Avant iadd :
5
3

Après iadd ;
8

Wiki (seule source que j'ai trouvé...) semble me donner raison : http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

Voici ce que je comprends : http://pastebin.com/7urRYkT4

De ce que j'ai lu, la compil' ne fait pas d'optim (ou peu), c'est la JVM qui s'en charge.

pseuuuuuuuuuudo
pseuuuuuuuuuudo
Niveau 10
09 janvier 2014 à 14:18:03

J'ai pas trouvé d'autres sources que Wiki non plus, c'est pour ça que je rame un peu sur les détails :o))

Et sinon j'ai capté du coup, les istore correspondent en fait aux variables utilisées dans la méthode, ça correspond à une assignation, merci pour ça !

Et enfin, le "la compil' ne fait pas d'optim" m'a aussi permis d'y voir plus clair, dans ma tête c'était plutôt l'inverse mais en fait la compil se fait bien instruction par instruction sans chercher plus loin.

Bref merci, j'y vois déjà un peu plus clair !

Bunyan
Bunyan
Niveau 17
09 janvier 2014 à 15:15:51

Change ton res = a + 5 par res = a + 9 ;)

[notch]
[notch]
Niveau 10
09 janvier 2014 à 16:03:22

iload_1 ;On charge le premier entier donné en paramètre au sommet de la pile.

iconst_5 ;On ajoute l'entier 5 au sommet de la pile.

iadd ;On additionne les deux entiers du sommet de la pile (qui sont retiré) et le résultat est ajouté au sommet de la pile.

istore_2 ;On stocke la valeur au dessus de la pile (le résultat que l'on a obtenu) dans la case n°2 du tableau des variables locales (sachant qu'un tableau commence par 0). La valeur qui a été stocké est retiré de la pile.

iload_2 ;On charge le contenu de la case n°2 du tableau des variables locales (Ces deux dernières opérations ont ainsi permis de stocker le résultat et de l'avoir au sommet de la pile).

ireturn ;Et on retourne la valeur au sommet de la pile.

Si tu veux je peux te passer le cours que j'ai eu à la fac en pdf (mais faudra compléter avec un wiki). Par contre c'est du jasmin donc pas exactement la même syntaxe.

pseuuuuuuuuuudo
pseuuuuuuuuuudo
Niveau 10
09 janvier 2014 à 18:50:01

Merci pour les précisions sur le fonctionnement du stack. La variable locale #0 est utilisée pour stocker this je suppose ? Vu que ça commence à 1 pour les paramètres de la méthode et que le 0 est pas utilisé ailleurs...

Je veux bien ton pdf de cours [notch], Jasmin a l'air de ressembler pas mal au bytecode désassemblé donc ça peut pas faire de mal :) Et je compte pas aller chercher dans les concepts les plus avancée, j'essaie juste d'avoir un aperçu du bytecode donc ça devrait aller.

Bon et au final j'ai pu me convaincre qu'on pouvait optimiser en supprimant les instructions 3 et 4, au final ça revient plus ou moins à écrire http://pastebin.com/Wc71j3Xt au lieu de http://pastebin.com/hBLh1M13 , en faisant comme ça la valeur au dessus de la pile est directement retournée sans passer par la locale res. Y a bien pas d'optimisation faite par le compilo.

papy386
papy386
Niveau 10
10 janvier 2014 à 10:12:35

Bonjour

iload_1 Charge la 1e entier depuis la variable locale (pas sur la pile mais en mémoire)!

iconst_5 Charge le 5e entier depuis la pile (et non sur la pile!)

iadd ajoute les 2 entiers (depuis la mémoire, vers la mémoire).

istore_2 enregistre l'entier en mémoire dans la 2e variable (donc en mémoire).

iload_2 charge le 2e entier depuis la variable locale.

iload_2 retourne l'entier en mémoire.

Bref il n'y a pas que la pile, mais aussi les registres a prendre en compte (enfin si on compte les variables en mémoires comme registres).

Sous forums
  • Aide à l'achat Mac
  • Steam Deck
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Macintosh
  • Hardware
La vidéo du moment