/** * Traduction "machine" du programme Simple.java. * Il s'agit demontrer comment un appel de fonction est réalisé. * Pour cela des conventions d'appel sont nécessaires : * - qu'est ce qui est transmis et dans quel ordre ? * - qui empile et dépile ? * * Toute convention fonctionnelle est correcte, même si certaines sont plus * malines que d'autres. * Ici nous avons convenu de : * - on transmet sur la pile en empilant dans l'ordre : l'adresse de retour, * puis les paramètres dans l'ordre de leur apparition dans la définition * - l'appellant empile ET dépile tout lui-même. * * L'effet important à noter (au-delà de la convention) est qu'une fonction * accède donc à ses arguments, etc directement DANS la pile, et donc via * des adresses relatives! */ public class SimpleTraduit { public static void main(String []a) { // v:0 // 1.. : la pile int []memoire = new int[1000]; int instructionCourante = 1; boolean fin = false; int sommetDePile = 1; // adresse du debut de la pile while (!fin) { switch(instructionCourante) { // boucle for case 1: // v = 0; memoire[0] = 0; break; case 2: // test v<10 ? if (memoire[0]<10) instructionCourante = 3-1; // saut 1ere ins. boucle else instructionCourante = 12-1; // saut après boucle break; case 3: // 1ere ins. du corps de la boucle System.out.println("avant appel f()"); break; case 4: // seconde instruction du corps de la boucle // préparation de l'appel, i.e. empile dans l'ordre "retour","arguments" // push (adresseDeRetour) memoire[sommetDePile] = 7-1; // on devra retourne en 7 sommetDePile++; break; case 5: // push(v) memoire[sommetDePile] = memoire[0]; sommetDePile++; break; case 6: // saut vers le debut de la fonction f instructionCourante = 1000-1; // tout est prêt break; case 7: // retour de l'appel on nettoie les choses devenues inutiles sommetDePile -= 1; // pop valeur transmise break; case 8: sommetDePile -= 1; // pop adresse de retour break; case 9: // instruction qui suit l'appel à f() System.out.println("apres appel f()"); break; case 10: // v++, fin du corps de la boucle memoire[0]++; break; case 11: // retour au for... instructionCourante = 2-1; break; case 12: // après la boucle for System.out.println("Termine"); break; case 13: // appel à f(50) memoire[sommetDePile] = 16-1; // adresse de retour 16 sommetDePile++; break; case 14: // paramètre de valeur 50 memoire[sommetDePile] = 50; sommetDePile++; break; case 15: // hop saut vers f() instructionCourante = 1000-1; break; case 16: // retour de l'appel sommetDePile--; // pop devenu inutile break; case 17: sommetDePile--; // pop devenu inutile break; case 18: // fin du programme fin = true; break; case 1000: // debut de la fonction f System.out.println("Voici la variable i : "+memoire[sommetDePile-1]); break; case 1001: // return : retour à l'appelant... instructionCourante = memoire[sommetDePile-2]; break; } instructionCourante++; } System.out.println("Le somme de pile est : "+sommetDePile); } }