semaine 5
This commit is contained in:
parent
73cf83dbee
commit
16fb5d0347
@ -127,8 +127,134 @@ Dessinez les automates qui reconnaissent :
|
|||||||
### Compter avec les automates
|
### Compter avec les automates
|
||||||
On ne le verra pas dans ce cours, mais il est possible d'établir que le modèle des automates ne permet pas de compter. Par exemple, on ne peut pas lire une expression avec des parenthèses et vérifier qu'il y a autant de parenthèses ouvrantes que de parenthèses fermantes. On ne peut pas non plus vérifier que les parenthèses correspondent bien. Ainsi ce modèle n'est pas suffisant pour vérifier par exemple qu'une chaîne de caractères est un programme suivant un syntaxe fixée du C.
|
On ne le verra pas dans ce cours, mais il est possible d'établir que le modèle des automates ne permet pas de compter. Par exemple, on ne peut pas lire une expression avec des parenthèses et vérifier qu'il y a autant de parenthèses ouvrantes que de parenthèses fermantes. On ne peut pas non plus vérifier que les parenthèses correspondent bien. Ainsi ce modèle n'est pas suffisant pour vérifier par exemple qu'une chaîne de caractères est un programme suivant un syntaxe fixée du C.
|
||||||
|
|
||||||
Par contre, on peut compter facilement modulo N, puisque celà revient à se souvenir
|
Par contre, on peut compter facilement modulo N, puisque celà revient à se souvenir d'un nombre fini de cas.
|
||||||
|
|
||||||
|
NB. modulo N veut dire qu'on manipule des nombres en faisant des sommes, des produits, etc mais en s'intéressant uniquement au reste de la division par N du résultat. Ça semble abstrait au premier abord, mais c'est ce que vous faites quand vous calculez le numéro d'un mois avec N=12.
|
||||||
|
Par exemple 3 mois après novembre c'est février : soit 11+3 = 2 modulo 12.
|
||||||
|
|
||||||
|
Imaginons que notre automate lise un mot sur l'alphabet 0,1 représentant en binaire un nombre et qu'on souhaite tester si ce nombre est un multiple de 3.
|
||||||
|
|
||||||
|
#### Retour sur la notation binaire
|
||||||
|
|
||||||
|
En décimal, si j'ajoute 0 à droite d'un mot décimal w qui représente le nombre n alors le mot décimal w0 (w suivi d'un 0) représente n fois 10.
|
||||||
|
|
||||||
|
En binaire, c'est similaire mais en remplaçant 10 par 2 dans la phrase ci-dessus.
|
||||||
|
Donc w0 représente 2n.
|
||||||
|
|
||||||
|
Si j'écris w1 c'est le nombre représenté par w0 plus 1, soit 2n+1.
|
||||||
|
|
||||||
|
On peut utiliser cette relation pour déduire des propriétés de divisibilité par trois des nombres représentés par w0 ou w1 en fonction de celle du nombre n représenté par w.
|
||||||
|
|
||||||
|
Si n est divisible par trois, il s'écrit sous la forme 3k pour un certain k.
|
||||||
|
* 2n vaut dans ce cas 2*3k qui est encore divisible par 3 (reste nul, soit 0 modulo 3).
|
||||||
|
* 2n+1 vaut dans ce cas 2(3k)+1 (reste 1, soit 1 modulo 3).
|
||||||
|
|
||||||
|
On peut procéder de même pour les 2 autres cas.
|
||||||
|
|
||||||
|
Si le reste de la division de n par trois vaut 1, il s'écrit sous la forme 3k+1 pour un certain k.
|
||||||
|
* 2n vaut dans ce cas 2(3k+1)=2.3k+2 (reste 2, soit 2 modulo 3).
|
||||||
|
* 2n+1 vaut dans ce cas 2(3k+1)+1=2.3k+3=3(2k+1) (reste 0, soit 0 modulo 3).
|
||||||
|
|
||||||
|
##### Exercice
|
||||||
|
Procédez de même lorsque le reste de la division de n par trois vaut 2.
|
||||||
|
|
||||||
|
En déduire un automate qui lit un mot en binaire et accepte celui-ci exactement lorsque le nombre représenté est divisible par trois.
|
||||||
|
(indication : il faut un état par reste possible).
|
||||||
|
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## Le modèle de la machine de Turing
|
||||||
|
Nous allons maintenant nous pencher sur un modèle de machine qui
|
||||||
|
semble au premier abord n'être que légèrement différent de celui des
|
||||||
|
automates. D'une part, on va pouvoir revenir en arrière sur le mot, et
|
||||||
|
d'autre part on va pouvoir écrire ce qui permet d'avoir une mémoire
|
||||||
|
arbitrairement grande.
|
||||||
|
|
||||||
|
Ces deux changements permettent
|
||||||
|
d'obtenir *in fine* un modèle très riche puisque *n'importe quelle
|
||||||
|
procédure de calcul connue à l'heure actuelle* peut être traduite
|
||||||
|
théoriquement par une machine de Turing.
|
||||||
|
|
||||||
|
Il est important de noter que le programme reste fini.
|
||||||
|
|
||||||
|
|
||||||
|
![images/turingMachine.png]
|
||||||
|
|
||||||
|
Il y a beaucoup de ressources sur Alan Turing disponibles en ligne, en
|
||||||
|
particulier depuis son centenaire en 2012. Vous pouvez trouver (ses
|
||||||
|
articles originaux et ses brouillons)[http://www.turingarchive.org/].
|
||||||
|
|
||||||
|
C'est un mathématicien qui a eu une influente forte en informatique,
|
||||||
|
malgré une vie trop courte (1912-1954). En droit britannique, (une loi porte son nom)[https://en.wikipedia.org/wiki/Alan_Turing_law}]
|
||||||
|
|
||||||
|
### Turing avec JFLAP
|
||||||
|
|
||||||
|
Dans le menu choisissez **Machine de Turing**. L'éditeur graphique vous permet de créer rapidement le programme d'une machine de Turing. Les cercles sont les états de la machine (comme pour les automates). Un clic droit permet de rendre initial un état, ou final des états. Un état final correspond ici en fait à un état acceptant. La machine s'arrête si il n'y a pas de transition appropriée (en
|
||||||
|
rejetant si l'état dans laquelle elle se trouve n'est pas final).
|
||||||
|
|
||||||
|
Dans la suite on utilise l'alphabet 0,1 en plus du blanc (ressemblant à un carré pour JFLAP).
|
||||||
|
Notez que le ruban est infini à gauche et à droite pour JFLAP. Il y a
|
||||||
|
de nombreuses variations possibles pour la machine de Turing qui ne
|
||||||
|
font pas de différence notable, par exemple un ruban fini à gauche, un ruban à 2 dimensions etc.
|
||||||
|
|
||||||
|
Un point technique avec JFLAP. Si vous voulez fabriquer une transition
|
||||||
|
qui écrit un blanc (un carré) pour une transition, il suffit de ne rien
|
||||||
|
saisir dans cette cellule pour la transition et d'appuyer sur entrée.
|
||||||
|
|
||||||
|
#### Exercice
|
||||||
|
On suppose que l'alphabet est 0,1
|
||||||
|
1. Écrire un programme qui lit les caractères du mot d'entrée de
|
||||||
|
la gauche vers la droite et s'arrête en acceptant.
|
||||||
|
1. Même question pour un programme qui accepte si et seulement si
|
||||||
|
la première et la dernière lettre sont les mêmes.
|
||||||
|
1. Même question pour les mots qui sont des \textsl{palindromes}
|
||||||
|
(exemple de palindrome en français KAYAK). On peut dans un premier
|
||||||
|
temps ne gérer correctement que les mots qui sont de longueur
|
||||||
|
paire.
|
||||||
|
|
||||||
|
#### Indications + correction indicative
|
||||||
|
Pour les palindromes pairs, de la forme w suivi de w renversé, *on ne peut pas se souvenir dans nos états* du début du mot w qui est arbitrairement grand et donc pour un mot
|
||||||
|
assez grand forcément plus grand que le nombre (fini) d'états de notre
|
||||||
|
machine.
|
||||||
|
|
||||||
|
Si on disposez d'une machine de Turing à **2 rubans**, on pourrait :
|
||||||
|
recopier le premier ruban sur le second; ramener la tête de lecture du
|
||||||
|
premier ruban tout à gauche; puis décaler la tête du premier ruban
|
||||||
|
vers la droite et celle du second ruban vers la gauche en vérifiant
|
||||||
|
une par une que les lettres sont identiques.
|
||||||
|
|
||||||
|
Comme nous ne disposons que d'un ruban, la seule mémoire non bornée à
|
||||||
|
notre disposition est l'unique ruban. L'idée consiste donc à vérifier
|
||||||
|
l'un après l'autre les couples de lettres suivantes : (première
|
||||||
|
lettre, dernière lettre) puis (seconde lettre, avant-dernière lettre)
|
||||||
|
etc.
|
||||||
|
|
||||||
|
Si nous avions **deux têtes** il suffirait de placer notre seconde tête à
|
||||||
|
la fin du mot et de procéder comme dans la version à 2 rubans.
|
||||||
|
|
||||||
|
Puisqu'on a une seule tête, cette dernière va devoir faire des
|
||||||
|
aller-retours. Il va falloir marquer d'une manière ou d'une autre les
|
||||||
|
lettres qu'on a vu pour éviter de repasser au même endroit.
|
||||||
|
L'exemple ci-dessous enlève tout simplement les lettres en cours de
|
||||||
|
vérification.
|
||||||
|
|
||||||
|
![images/TuringPalindromePair.jpg]
|
||||||
|
|
||||||
|
## La thèse de Church Turing.
|
||||||
|
**Pour tout modèle raisonnable de calcul, on obtient la même notion de ce qui est calculable.**
|
||||||
|
|
||||||
|
|
||||||
|
Arguments en faveur de cette thèse
|
||||||
|
* Théorie générales des fonctions récursives (Gödel, Herbrand
|
||||||
|
1933).
|
||||||
|
* lambda-calcul (Church, 1936).
|
||||||
|
* Machines de Turing (Turing, 1936).
|
||||||
|
* Trois modèles équivalents (Church 1936, Turing 1937).
|
||||||
|
* Machines de Post (1936).
|
||||||
|
* Machines de Turing avec plusieurs rubans (Minsky).
|
||||||
|
* Machines à compteurs.
|
||||||
|
* Machines à registre.
|
||||||
|
* etc.
|
||||||
|
|
||||||
|
333
5ComputationAndData.md
Normal file
333
5ComputationAndData.md
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
Cours de Florent.
|
||||||
|
|
||||||
|
# Calculer en théorie et en pratique III/III
|
||||||
|
|
||||||
|
Dans cette séquence de cours, nous tentons de répondre à la question suivante.
|
||||||
|
|
||||||
|
C'est quoi un ordinateur?
|
||||||
|
|
||||||
|
Cette question s'apparente à celle que ce sont posés philosophes et mathématiciens de Leibnitz à Turing en passant par Hilbert.
|
||||||
|
|
||||||
|
Qu'est-ce qu'une question à laquelle on peut répondre de manière mécanique par un calcul?
|
||||||
|
|
||||||
|
Nous avons vu une approximation de calcul théorique basé sur le calcul booléen et des portes logiques qui sont implémentable avec des composants electroniques, permettant de réaliser divers opérations comme l'addition bit à bit (schéma de Vernam en cryptographie), la majorité ou encore l'addition avec retenue.
|
||||||
|
|
||||||
|
Nous avons poursuivi avec un modèle théorique, qui est celui de l'**automate fini**, un modèle assez restreint de machine : l'adjectif fini s'applique à la mémoire de la machine qui est finie.
|
||||||
|
Nous avons entrevu le modèle plus général avec une mémoire arbitrairement grande **la machine de Turing** et évoqué la thèse de Church-Turing qui stipule que tout modèle de calcul raisonnable est équivalent à ce modèle de la machine de Turing.
|
||||||
|
|
||||||
|
Toutefois, le modèle de la machine de Turing reste assez éloigné d'une machine réelle et nous allons maintenant présenter rapidement un modèle simplifié de machine basé sur le modèle de Von Neumann, puis pratiquer l'assembleur avec la Machine Virtuelle à Pile (MVàP).
|
||||||
|
|
||||||
|
|
||||||
|
## Programme vs données
|
||||||
|
|
||||||
|
Dans le modèle de Turing, le programme est externe et guide la machine qui travaille sur le contenu du ruban qu'on peut voir comme la donnée.
|
||||||
|
Dès 1936, Turing montre qu'en fait on peut construire une machine **universelle** qui lit sur son ruban le programme et les données sur lesquelles il faut lancer le calcul de ce programme.
|
||||||
|
|
||||||
|
C'est cette idée de "programme qu'on va charger" qu'on retrouve dans le modèle de Von Neumann.
|
||||||
|
|
||||||
|
|
||||||
|
## Le modèle de Von Neumann
|
||||||
|
|
||||||
|
* L'unité de Mémoire contient des *données* et *des insructions*
|
||||||
|
* Le processeur se compose d'une *unité de contrôle* et d'une *unité arithmétique et logique*.
|
||||||
|
* La communication avec l'extérieur se fait par des dispositifs d'entrée-sortie.
|
||||||
|
|
||||||
|
Pour plus de détails, voir [wikipedia](https://en.wikipedia.org/wiki/Von_Neumann_architecture)
|
||||||
|
|
||||||
|
## Zoom sur *l'unité arithmétique et logique*
|
||||||
|
|
||||||
|
Essentiellement un circuit au sens de ce qu'on a évoqué lors du dernier cours.
|
||||||
|
En pratique les entrées/sorties sont découpées en 2 dimensions : une partie **contrôle** et une partie **données**.
|
||||||
|
|
||||||
|
* [Image](https://commons.wikimedia.org/wiki/File:ALU_block.gif)
|
||||||
|
* [wikipedia](https://en.wikipedia.org/wiki/Arithmetic_logic_unit)
|
||||||
|
* [Symboles circuit](https://en.wikipedia.org/wiki/Electronic_symbol)
|
||||||
|
|
||||||
|
|
||||||
|
## Zoom sur la mémoire
|
||||||
|
|
||||||
|
La mémoire peut être vue comme une pyramide.
|
||||||
|
|
||||||
|
* En haut très peu de place, mais de la mémoire très rapide, ce sont des *registres*.
|
||||||
|
* Au milieu, de la mémoire assez rapide, c'est la *mémoire vive* (la RAM) qui n'est pas persistante et quand on étend la machine, le contenu de la mémoire n'est pas conservé.
|
||||||
|
* En bas, de la mémoire plutôt lente, mais persistante, typiquement le *disque dur*.
|
||||||
|
|
||||||
|
En pratique il existe des mécanismes de *cache*, en particulier entre les registres et la RAM.
|
||||||
|
|
||||||
|
Il y a d'autres ingrédients qui permettent de limiter l'emprunte en mémoire d'un programme (adresses virtuelles, paging) voir de suspendre une exécution et de recopier le programme en train de calculer dans le disque (swapping).
|
||||||
|
|
||||||
|
* [Image](images/4-hierarchy.jpg)
|
||||||
|
* [Jeu du paging](https://en.wikisource.org/wiki/Paging)
|
||||||
|
* [Cache vs paging](https://stackoverflow.com/questions/4429025/caches-vs-paging)
|
||||||
|
|
||||||
|
## la Machine Virtuelle à Pile (MVàP).
|
||||||
|
|
||||||
|
Normalement dans une machine il faudrait expliquer comment les calculs sont poussés vers les registres et l'ALU.
|
||||||
|
Nous allons travailler avec un modèle simplifié qui cache cet aspect et dans laquelle la mémoire est une pile.
|
||||||
|
|
||||||
|
Par ailleurs la machine possèdes deux registres.
|
||||||
|
* PC (pour Program counter) qui contient le numéro de la ligne d'instruction en cours
|
||||||
|
* FC (pour frame pointer) qui est un mécanisme permettant de faire des appels de fonctions mais qu'on n'utilisera pas car c'est un peu plus technique à utiliser.
|
||||||
|
|
||||||
|
La machine accepte plusieurs instructions.
|
||||||
|
```
|
||||||
|
PUSHI n # pousse l'entier n sur la pile et passe à l'instruction suivante
|
||||||
|
POP # décale le sommet de la pile d'un et passe à l'instruction suivante
|
||||||
|
|
||||||
|
ADD # ajoute les 2 entiers au sommet de la pile, décale le sommet de la pile de 2
|
||||||
|
# écrit le résultat en haut de la pile et passe à l'instruction suivante
|
||||||
|
SUB # même chose pour la soustraction
|
||||||
|
MUL # même chose pour la multiplication
|
||||||
|
DIV # même chose pour la division
|
||||||
|
|
||||||
|
READ # lecture d'un entier qui est poussé en haut de la pile
|
||||||
|
WRITE # écriture de l'entier en haut de la pile
|
||||||
|
|
||||||
|
HALT # fin du programme
|
||||||
|
|
||||||
|
LABEL x # définition d'une ancre vers laquelle on peut sauter
|
||||||
|
JUMP x # Saut vers le label (prochaine instruction à la ligne du label)
|
||||||
|
JUMPF x # Instruction suivante si le haut de la pile est différent de 0
|
||||||
|
# Instruction x sinon.
|
||||||
|
|
||||||
|
INF # Mange deux entiers.
|
||||||
|
# Remplace par l'entier 1 si le premier inférieur au second et par 0 sinon.
|
||||||
|
# Passe à l'instruction suivante
|
||||||
|
INFEQ # idem plus petit ou égal
|
||||||
|
SUP # idem plus grand
|
||||||
|
SUPEQ # idem plus grand ou égal
|
||||||
|
EQUAL # idem égal
|
||||||
|
NEQ # idem différent
|
||||||
|
|
||||||
|
# Autres instructions qu'on verra plus tard.
|
||||||
|
PUSHG a # empile en haut de la pile l'entier stocké à l'adresse a de la pile
|
||||||
|
STOREG a # dépile et stocke à l'adresse a de la pile l'entier en haut de la pile
|
||||||
|
|
||||||
|
# Autres instructions qu'on ne verra probablement pas plus tard.
|
||||||
|
CALL x # Appel du code stocké au label x
|
||||||
|
RETURN # Retour dans le code appellant.
|
||||||
|
PUSHL a # analogue de PUSHG pour des variables locales (utilise FP)
|
||||||
|
STOREL a # analogue de STOREG
|
||||||
|
```
|
||||||
|
|
||||||
|
### Un premier exemple
|
||||||
|
|
||||||
|
```
|
||||||
|
PUSHI 11
|
||||||
|
PUSHI 6
|
||||||
|
PUSHI 15
|
||||||
|
MUL
|
||||||
|
SUB
|
||||||
|
PUSHI 5
|
||||||
|
ADD
|
||||||
|
PUSHI 12
|
||||||
|
ADD
|
||||||
|
PUSHI 9
|
||||||
|
PUSHI 4
|
||||||
|
MUL
|
||||||
|
PUSHI 7
|
||||||
|
MUL
|
||||||
|
ADD
|
||||||
|
WRITE
|
||||||
|
POP
|
||||||
|
HALT
|
||||||
|
```
|
||||||
|
|
||||||
|
Une fois assemblé, le code devient :
|
||||||
|
```
|
||||||
|
Adr | Instruction
|
||||||
|
-----+---------------
|
||||||
|
0 | PUSHI 11
|
||||||
|
2 | PUSHI 6
|
||||||
|
4 | PUSHI 15
|
||||||
|
6 | MUL
|
||||||
|
7 | SUB
|
||||||
|
8 | PUSHI 5
|
||||||
|
10 | ADD
|
||||||
|
11 | PUSHI 12
|
||||||
|
13 | ADD
|
||||||
|
14 | PUSHI 9
|
||||||
|
16 | PUSHI 4
|
||||||
|
18 | MUL
|
||||||
|
19 | PUSHI 7
|
||||||
|
21 | MUL
|
||||||
|
22 | ADD
|
||||||
|
23 | WRITE
|
||||||
|
24 | POP
|
||||||
|
25 | HALT
|
||||||
|
```
|
||||||
|
La MVàP, en mode debug, écrit à chaque pas :
|
||||||
|
|
||||||
|
* la valeur du compteur de programme (pc) ;
|
||||||
|
* l'instruction à cette adresse ;
|
||||||
|
* la valeur du « frame pointer » (toujours 0, quand il n'y a pas d'appel de fonction) ;
|
||||||
|
* le contenu de la pile ;
|
||||||
|
* la hauteur de la pile.
|
||||||
|
|
||||||
|
Le début de l'exécution donne la trace suivante :
|
||||||
|
|
||||||
|
```
|
||||||
|
pc | | fp pile
|
||||||
|
====================================================
|
||||||
|
0 | PUSHI 11 | 0 [ ] 0 # On empile 11
|
||||||
|
2 | PUSHI 6 | 0 [ 11 ] 1 # On empile 6
|
||||||
|
4 | PUSHI 15 | 0 [ 11 6 ] 2 # On empile 15
|
||||||
|
6 | MUL | 0 [ 11 6 15 ] 3 # On dépile et multiplie 6*15, on empile le résultat
|
||||||
|
7 | SUB | 0 [ 11 90 ] 2 # On dépile et soustrait 90 à 11, on empile le résultat.
|
||||||
|
8 | PUSHI 5 | 0 [ -79 ] 1 # On empile 5.
|
||||||
|
etc
|
||||||
|
```
|
||||||
|
### Exercice
|
||||||
|
|
||||||
|
Continuez l'exécution.
|
||||||
|
|
||||||
|
### Exercice
|
||||||
|
|
||||||
|
Vérifier votre calcul manuel en lançant la machine.
|
||||||
|
|
||||||
|
Il faut avoir java installé sur votre machine ou utiliser proxmox.
|
||||||
|
Il faut utiliser les deux fichiers jar qui sont dans le répertoire MVaP
|
||||||
|
Le fichier ```MVaP/ALIRE``` contient la marche à suivre.
|
||||||
|
|
||||||
|
### Variables globales
|
||||||
|
On peut réserver de l'espace en bas de la pile et associer à une variable sa position pour mémoriser des valeurs.
|
||||||
|
|
||||||
|
```
|
||||||
|
PUSHI 1 # Il faut initialement pousser une valeur ( par exemple 1)
|
||||||
|
... # Du code qui génère des choses dans la pile et une valeur en haut de la pile, par exemple 42
|
||||||
|
STOREG 0 # stocke 42 à l'adresse 0 de la pile (le 1 est remplacé par 42)
|
||||||
|
... # Du code qui fait des choses et qui tout à coup a besoin de connaître la valeur stockée
|
||||||
|
PUSHG 0 # empile 42 en haut de la pile.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exemple
|
||||||
|
|
||||||
|
Imaginons qu'on souhaite faire du code qui :
|
||||||
|
* déclare une variable i
|
||||||
|
* lui affecte la valeur 6
|
||||||
|
* plus tard souhaite l'incrémenter.
|
||||||
|
|
||||||
|
```
|
||||||
|
PUSHI 1 # i habite à l'adresse 0
|
||||||
|
...
|
||||||
|
PUSHI 6
|
||||||
|
STOREG 0
|
||||||
|
...
|
||||||
|
PUSHI 1
|
||||||
|
PUSHG 0
|
||||||
|
ADD
|
||||||
|
STOREG 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Boucles
|
||||||
|
|
||||||
|
Imaginons qu'on souhaite faire une boucle tant que
|
||||||
|
```
|
||||||
|
Tant que test :
|
||||||
|
quelque chose
|
||||||
|
La suite
|
||||||
|
```
|
||||||
|
Il faut utiliser des labels pour délimiter
|
||||||
|
* la partie test suivie de la décision de rentrer dans la boucle ou de sortir
|
||||||
|
* la partie interne à la boucle (quelque chose)
|
||||||
|
* la partie qui suit la boucle (La suite).
|
||||||
|
|
||||||
|
```
|
||||||
|
LABEL 0
|
||||||
|
# le test qui va laisser une valeur 0 ou 1 en haut de la pile
|
||||||
|
JUMPF 1 # saut conditionnel vers le label 1 si le test est Faux sinon continue
|
||||||
|
# quelque chose
|
||||||
|
LABEL 1
|
||||||
|
#La suite
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exercice
|
||||||
|
|
||||||
|
Produire du code MVàP qui correspond au code python suivant.
|
||||||
|
```python
|
||||||
|
j = 1
|
||||||
|
i = 0
|
||||||
|
i = j
|
||||||
|
while i < 10:
|
||||||
|
i += 1
|
||||||
|
print(i)
|
||||||
|
```
|
||||||
|
Testez votre code avec la MVàP.
|
||||||
|
|
||||||
|
### Exercice
|
||||||
|
Produire du code MVàP qui correspond au code python suivant.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# integer inputs (input returns a string that needs casting as an int)
|
||||||
|
m = int(input())
|
||||||
|
n = int(input())
|
||||||
|
if (m < n) :
|
||||||
|
m = n
|
||||||
|
else :
|
||||||
|
n = m
|
||||||
|
print m
|
||||||
|
print n
|
||||||
|
```
|
||||||
|
|
||||||
|
### Réutiliser du code.
|
||||||
|
|
||||||
|
Si on a du code qu'on veut réutiliser plusieurs fois,
|
||||||
|
* on peut l'isoler entre un label et un jump
|
||||||
|
* on peut sauter vers le label
|
||||||
|
* malheureusement on ne peut pas sauter à la fin vers plusieurs endroits différents
|
||||||
|
* on pourrait faire des tests successifs avec des JUMP et des JUMPF pour sauter au bon endroit
|
||||||
|
* par contre on ne peut pas réutiliser le code un nombre arbitraire de fois.
|
||||||
|
|
||||||
|
Solution : on sauve dans un registre l'endroit dans lequel on doit retourner
|
||||||
|
Le plus simple consiste à utiliser le haut de la pile.
|
||||||
|
|
||||||
|
Par contre il faut dans ce cas une instruction pour la MVàP qui permette d'écrire en haut de la pile la position actuelle du pc (c'est une partie du rôle de CALL) et il faut une instruction qui soit l'analogue de HALT pour un bloc et permette de retourner le pc à la valeur antérieure à l'appel (c'est une partie du rôle de RETURN).
|
||||||
|
|
||||||
|
Avec cette idée on peut faire un appel à une fonction qui ne prend pas de paramètre et ne retourne pas de valeur.
|
||||||
|
|
||||||
|
On peut communiquer avec le reste du programme via une variable globale.
|
||||||
|
|
||||||
|
### Exemple
|
||||||
|
On peut ainsi par exemple faire une fonction qui mutliplie par 2 une variable globale.
|
||||||
|
On appelle 3 fois la fonction et on affiche le résultat à chaque fois.
|
||||||
|
|
||||||
|
```
|
||||||
|
PUSHI 1 # variable globale i habite à l'adresse 0
|
||||||
|
JUMP 1
|
||||||
|
LABEL 0 # Notre Fonction
|
||||||
|
PUSHG 0
|
||||||
|
PUSHI 2
|
||||||
|
MUL
|
||||||
|
STOREG 0
|
||||||
|
RETURN # Fin de Notre Fonction
|
||||||
|
...
|
||||||
|
LABEL 1 # Main
|
||||||
|
CALL 0 # appel 1
|
||||||
|
PUSHG 0
|
||||||
|
WRITE
|
||||||
|
CALL 0 # appel 2
|
||||||
|
PUSHG 0
|
||||||
|
WRITE
|
||||||
|
CALL 0 # appel3
|
||||||
|
PUSHG 0
|
||||||
|
WRITE
|
||||||
|
```
|
||||||
|
|
||||||
|
## Autres Exercices
|
||||||
|
Il faut pour chaque exercice produire et tester du code MVàP qui réaliser le calcul ou le programme demandé.
|
||||||
|
|
||||||
|
### Exercice
|
||||||
|
Lire un entier n et calculez n*4+5*6-2
|
||||||
|
|
||||||
|
### Exercice
|
||||||
|
Lire un entier n et calculez 2*4+n*6-2
|
||||||
|
|
||||||
|
### Exercice
|
||||||
|
Même chose que ci-dessus mais avec un programme optimisé (qui donne le même résultat mais avec un minimum d'instructions).
|
||||||
|
|
||||||
|
### Exercice
|
||||||
|
Lire un entier n. Si n est nul le programme écrit 20 sinon 10.
|
||||||
|
|
||||||
|
### Exercice
|
||||||
|
Et parce qu'il faut bien une question un peu plus difficile.
|
||||||
|
Lire un entier n. Le programme écrit 2^n.
|
BIN
5ComputationAndData/5CM-MVaP.pdf
Normal file
BIN
5ComputationAndData/5CM-MVaP.pdf
Normal file
Binary file not shown.
BIN
5ComputationAndData/6CM-Func.pdf
Normal file
BIN
5ComputationAndData/6CM-Func.pdf
Normal file
Binary file not shown.
254
5ComputationAndData/6TD.html
Normal file
254
5ComputationAndData/6TD.html
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="fr-FR">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>TD6 --- L3 -- Langage et Compilation</title>
|
||||||
|
<link rel="stylesheet" href="../styletp.css" type="text/css" media="screen, print">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>TD6 --- L3 Langage et Compilation --</h1>
|
||||||
|
<h1>Le retour de la MVàP</h1>
|
||||||
|
|
||||||
|
Fort de notre expériennce de la semaine passée, nous continuons à programmer en MVàP. Pour ceux qui regrettent le python et ces fonctions : pas de problème
|
||||||
|
la MVàP permet d'en écrire, et à la fin de ce TD en salle machine, les fonctions n'auront plus de secrets pour vous.
|
||||||
|
|
||||||
|
<h2>Préliminaire</h2>
|
||||||
|
Sortez un papier, un crayon et une gomme. Imaginez pour l'instant que le pc devant vous sert seulement à visionner cette feuille d'exercice.
|
||||||
|
|
||||||
|
|
||||||
|
<a id="code"></a>
|
||||||
|
<h2>Code MVàP 1</h2>
|
||||||
|
Soit le programme suivant en MVàP :
|
||||||
|
<pre>
|
||||||
|
JUMP 0
|
||||||
|
LABEL 1
|
||||||
|
PUSHL -3
|
||||||
|
PUSHI 2
|
||||||
|
MUL
|
||||||
|
STOREL -4
|
||||||
|
RETURN
|
||||||
|
RETURN
|
||||||
|
LABEL 0
|
||||||
|
PUSHI 0
|
||||||
|
PUSHI 2
|
||||||
|
CALL 1
|
||||||
|
POP
|
||||||
|
WRITE
|
||||||
|
POP
|
||||||
|
HALT
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Une fois assemblé, ce code devient :
|
||||||
|
<pre>
|
||||||
|
Adr | Instruction
|
||||||
|
-----+---------------
|
||||||
|
0 | JUMP 11
|
||||||
|
2 | PUSHL -3
|
||||||
|
4 | PUSHI 2
|
||||||
|
6 | MUL
|
||||||
|
7 | STOREL -4
|
||||||
|
9 | RETURN
|
||||||
|
10 | RETURN
|
||||||
|
11 | PUSHI 0
|
||||||
|
13 | PUSHI 2
|
||||||
|
15 | CALL 2
|
||||||
|
17 | POP
|
||||||
|
18 | WRITE
|
||||||
|
19 | POP
|
||||||
|
20 | HALT
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<div class="question"> Commenter et compléter le début de trace suivant.
|
||||||
|
Commenter le code original. Que réalise-t-il?</div>
|
||||||
|
|
||||||
|
|
||||||
|
Le début de l'exécution donnant la trace suivante :
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
pc | | fp pile
|
||||||
|
====================================================
|
||||||
|
0 | JUMP 11 | 0 [ ] 0
|
||||||
|
11 | PUSHI 0 | 0 [ ] 0
|
||||||
|
13 | PUSHI 2 | 0 [ 0 ] 1
|
||||||
|
15 | CALL 2 | 0 [ 0 2 ] 2
|
||||||
|
2 | PUSHL -3 | 4 [ 0 2 17 0 ] 4
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<a id="code"></a>
|
||||||
|
<h2>Code MVàP 2</h2>
|
||||||
|
Soit le programme suivant en MVàP :
|
||||||
|
<pre>
|
||||||
|
JUMP 0
|
||||||
|
LABEL 1
|
||||||
|
PUSHL -3
|
||||||
|
PUSHI 2
|
||||||
|
MUL
|
||||||
|
STOREL -4
|
||||||
|
RETURN
|
||||||
|
RETURN
|
||||||
|
LABEL 2
|
||||||
|
LABEL 3
|
||||||
|
PUSHL -4
|
||||||
|
PUSHL -3
|
||||||
|
PUSHI 1
|
||||||
|
ADD
|
||||||
|
INF
|
||||||
|
JUMPF 4
|
||||||
|
PUSHI 0
|
||||||
|
PUSHL -3
|
||||||
|
CALL 1
|
||||||
|
POP
|
||||||
|
STOREL -4
|
||||||
|
JUMP 3
|
||||||
|
LABEL 4
|
||||||
|
PUSHL -4
|
||||||
|
STOREL -5
|
||||||
|
RETURN
|
||||||
|
RETURN
|
||||||
|
LABEL 0
|
||||||
|
PUSHI 0
|
||||||
|
PUSHI 3
|
||||||
|
PUSHI 5
|
||||||
|
CALL 2
|
||||||
|
POP
|
||||||
|
POP
|
||||||
|
WRITE
|
||||||
|
POP
|
||||||
|
HALT
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Une fois assemblé, ce code devient :
|
||||||
|
<pre>
|
||||||
|
Adr | Instruction
|
||||||
|
-----+---------------
|
||||||
|
0 | JUMP 38
|
||||||
|
2 | PUSHL -3
|
||||||
|
4 | PUSHI 2
|
||||||
|
6 | MUL
|
||||||
|
7 | STOREL -4
|
||||||
|
9 | RETURN
|
||||||
|
10 | RETURN
|
||||||
|
11 | PUSHL -4
|
||||||
|
13 | PUSHL -3
|
||||||
|
15 | PUSHI 1
|
||||||
|
17 | ADD
|
||||||
|
18 | INF
|
||||||
|
19 | JUMPF 32
|
||||||
|
21 | PUSHI 0
|
||||||
|
23 | PUSHL -3
|
||||||
|
25 | CALL 2
|
||||||
|
27 | POP
|
||||||
|
28 | STOREL -4
|
||||||
|
30 | JUMP 11
|
||||||
|
32 | PUSHL -4
|
||||||
|
34 | STOREL -5
|
||||||
|
36 | RETURN
|
||||||
|
37 | RETURN
|
||||||
|
38 | PUSHI 0
|
||||||
|
40 | PUSHI 3
|
||||||
|
42 | PUSHI 5
|
||||||
|
44 | CALL 11
|
||||||
|
46 | POP
|
||||||
|
47 | POP
|
||||||
|
48 | WRITE
|
||||||
|
49 | POP
|
||||||
|
50 | HALT
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<div class="question"> Compléter les traces d'exécution suivantes. Identifier les appels de fonctions. Repérer les blocs d'activation. Que réalise le code?</div>
|
||||||
|
|
||||||
|
|
||||||
|
Trace partielle :
|
||||||
|
<pre>
|
||||||
|
pc | | fp pile
|
||||||
|
====================================================
|
||||||
|
0 | JUMP 38 | 0 [ ] 0
|
||||||
|
38 | PUSHI 0 | 0 [ ] 0
|
||||||
|
40 | PUSHI 3 | 0 [ 0 ] 1
|
||||||
|
42 | PUSHI 5 | 0 [ 0 3 ] 2
|
||||||
|
44 | CALL 11 | 0 [ 0 3 5 ] 3
|
||||||
|
11 | PUSHL -4 |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
18 | INF | 5 [ 0 3 5 46 0 3 6 ] 7
|
||||||
|
19 | JUMPF 32 | 5 [ 0 3 5 46 0 1 ] 6
|
||||||
|
21 | PUSHI 0 | 5 [ 0 3 5 46 0 ] 5
|
||||||
|
23 | PUSHL -3 | 5 [ 0 3 5 46 0 0 ] 6
|
||||||
|
25 | CALL 2 | 5 [ 0 3 5 46 0 0 5 ] 7
|
||||||
|
2 | PUSHL -3 | 9 [ 0 3 5 46 0 0 5 27 5 ] 9
|
||||||
|
4 | PUSHI 2 | 9 [ 0 3 5 46 0 0 5 27 5 5 ] 10
|
||||||
|
6 | MUL | 9 [ 0 3 5 46 0 0 5 27 5 5 2 ] 11
|
||||||
|
7 | STOREL -4 | 9 [ 0 3 5 46 0 0 5 27 5 10 ] 10
|
||||||
|
9 | RETURN |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
11 | PUSHL -4 | 5 [ 0 10 5 46 0 ] 5
|
||||||
|
13 | PUSHL -3 | 5 [ 0 10 5 46 0 10 ] 6
|
||||||
|
15 | PUSHI 1 | 5 [ 0 10 5 46 0 10 5 ] 7
|
||||||
|
17 | ADD | 5 [ 0 10 5 46 0 10 5 1 ] 8
|
||||||
|
18 | INF | 5 [ 0 10 5 46 0 10 6 ] 7
|
||||||
|
19 | JUMPF 32 | 5 [ 0 10 5 46 0 0 ] 6
|
||||||
|
32 | PUSHL -4 | 5 [ 0 10 5 46 0 ] 5
|
||||||
|
34 | STOREL -5 | 5 [ 0 10 5 46 0 10 ] 6
|
||||||
|
36 | RETURN | 5 [ 10 10 5 46 0 ] 5
|
||||||
|
46 | POP | 0 [ 10 10 5 ] 3
|
||||||
|
47 | POP | 0 [ 10 10 ] 2
|
||||||
|
48 | WRITE | 0 [ 10 ] 1
|
||||||
|
10
|
||||||
|
49 | POP | 0 [ 10 ] 1
|
||||||
|
50 | HALT | 0 [ ] 0
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2>autocorrection</h2>
|
||||||
|
Vous pouvez éteindre votre papier, votre gomme et votre crayon et reprendre une activité normale.
|
||||||
|
Si ce n'est pas déjà fait la semaine dernière, téléchargez les <a href="MVaP.tar.gz">sources de la MVaP</a> et suivez les instructions avec les tests.
|
||||||
|
|
||||||
|
<div class="etape">
|
||||||
|
Utilisez la MVàP pour vérifier que celle ci ne se trompe pas et donne la même réponse que votre crayon.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a id="production"></a>
|
||||||
|
<h2>Production de code</h2>
|
||||||
|
|
||||||
|
Pour chaque programme décrit informellement ci-dessous, écrire un programme MVàP et testez le. Le fichier texte <code>.mvap</code> doit contenir une instruction par ligne et un saut de ligne après chaque instruction. Vous pouvez commenter votre code en préfixant chaque ligne par un dièse (hash). Attention à bien prendre soin de sauter une ligne y compris après la dernière instruction (HALT).
|
||||||
|
|
||||||
|
<div class="question">
|
||||||
|
Fonction f(x)=1-x. Fonction g(x)=1+x.
|
||||||
|
Main : appel de f(a)*g(a) pour un entier a lu auprès de l'utilisateur.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="question">
|
||||||
|
Fonction valeur absolue et son appel pour un entier entré par l'utilisateur.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="question">
|
||||||
|
Fonction 2^n (2 chapeau n c'est bien ça) et son appel pour un entier entré par l'utilisateur.
|
||||||
|
Évidemment on fera une fonction récursive sinon ce n'est pas drôle.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="question">
|
||||||
|
Fonction de Fibonnacci et appel d'ycelle dans le main pour 2 valeurs lues auprès de l'utilisateur.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Et parce qu'il faut bien une question un peu plus difficile.
|
||||||
|
<div class="question">
|
||||||
|
Reprendre la fonction chapeau. Codez là en récursion terminale.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body></html>
|
13
MVaP/3n+2.mvap
Normal file
13
MVaP/3n+2.mvap
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# calcule : 2 + 3 * n
|
||||||
|
PUSHI 2
|
||||||
|
LABEL 1
|
||||||
|
PUSHI 3
|
||||||
|
ADD
|
||||||
|
WRITE
|
||||||
|
DUP
|
||||||
|
PUSHI 100
|
||||||
|
INF
|
||||||
|
JUMPF 2
|
||||||
|
JUMP 1
|
||||||
|
LABEL 2
|
||||||
|
HALT
|
BIN
MVaP/3n+2.mvap.cbap
Normal file
BIN
MVaP/3n+2.mvap.cbap
Normal file
Binary file not shown.
36
MVaP/ALIRE
Normal file
36
MVaP/ALIRE
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# La machine virtuelle à pile.
|
||||||
|
|
||||||
|
Une machine pédagogique pour donner une idée de ce qu'est l'assembleur.
|
||||||
|
|
||||||
|
Dans le cadre d'un cours de compilation, par exemple en L3 informatique, on peut demander aux étudiants de coder un compilateur qui va transcrire un langage de haut niveau similaire à du python (sans objets et avec quelques types simples entiers, flottants, tableaux) vers du code MVàP.
|
||||||
|
|
||||||
|
## Contenu du répertoire.
|
||||||
|
* add.mvap Un exemple simple de programme
|
||||||
|
* 3n+2.mvap Un exemple moins simple de programme
|
||||||
|
* test.mvap Un exemple avec appel de fonction
|
||||||
|
|
||||||
|
* MVaP.jar Une archive java qui propose 2 exécutables
|
||||||
|
MVaPAssembler (assemble en un binaire)
|
||||||
|
CBaP (interprète le binaire).
|
||||||
|
|
||||||
|
* antlr-4.5.2-complete.jar Une archive java contenant de nombreux binaires permettant d'écrire des compilateurs sur lequel le code de la MVàP s'appuit.
|
||||||
|
|
||||||
|
## Pour utiliser la MVàP
|
||||||
|
|
||||||
|
Il faut avoir java d'installé sur sa machine (c'est le cas si vous passez par proxmox des machines de l'IUT).
|
||||||
|
|
||||||
|
** Pour exécuter du code mvap, il faut :
|
||||||
|
|
||||||
|
1- Assembler :
|
||||||
|
$ java -cp antlr-4.5.2-complete.jar:MVaP.jar MVaPAssembler add.mvap
|
||||||
|
ou avec des traces (option -d) :
|
||||||
|
$ java -cp antlr-4.5.2-complete.jar:MVaP.jar MVaPAssembler -d add.mvap
|
||||||
|
ce qui produit le fichier add.mvap.cbap
|
||||||
|
|
||||||
|
Le fichier .cbap (code binaire à pile) est du binaire que la machine peut exécuter.
|
||||||
|
|
||||||
|
2- Exécuter :
|
||||||
|
$ java -jar MVaP.jar add.mvap.cbap
|
||||||
|
ou pour mieux comprendre avec des traces :
|
||||||
|
$ java -jar MVaP.jar -d add.mvap.cbap
|
||||||
|
|
61
MVaP/ALIRE~
Normal file
61
MVaP/ALIRE~
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
add.mvap Un exemple simple de programme
|
||||||
|
3n+2.mvap Un exemple moins simple de programme
|
||||||
|
test.mvap Un exemple avec appel de fonction
|
||||||
|
MVaP.g4 Le parser du langage qui produit un analyseur ANTLR4
|
||||||
|
MVaPAssemblerListener.java Méthode appelée par le parcours de l'arbre d'analyse
|
||||||
|
qui produit du code binaire (CB)
|
||||||
|
MVaPAssembler.java L'assembleur qui produit du code binaire
|
||||||
|
Pile.java Un gestionnaire de pile d'entiers
|
||||||
|
CBaP.java La machine virtuelle pour le code binaire à pile
|
||||||
|
|
||||||
|
|
||||||
|
** Pour compiler l'assembleur et le machine virtuelle, il faut :
|
||||||
|
|
||||||
|
1- Avoir antlr dans son CLASSPATH :
|
||||||
|
$ export CLASSPATH=.:/usr/local/java/antlr-4.4-complete.jar
|
||||||
|
ou ajouter aux commandes : -cp .:/usr/local/java/antlr-4.4-complete.jar
|
||||||
|
|
||||||
|
2- Lancer antlr sur MVaP.g4
|
||||||
|
$ java -jar /usr/local/java/antlr-4.4-complete.jar MVaP.g4
|
||||||
|
|
||||||
|
3- Compiler l'assembleur et la machine virtuelle (il suffit de demander la
|
||||||
|
compilation des fichiers contenant les main, javac compilera les autres
|
||||||
|
classes automatiquement...)
|
||||||
|
$ javac MVaPAssembler.java CBaP.java
|
||||||
|
|
||||||
|
|
||||||
|
** Pour exécuter du code mvap, il faut :
|
||||||
|
|
||||||
|
1- Assembler :
|
||||||
|
$ java MVaPAssembler add.mvap
|
||||||
|
ou avec des traces :
|
||||||
|
$ java MVaPAssembler -d add.mvap
|
||||||
|
ce qui produit le fichier add.mvap.cbap
|
||||||
|
|
||||||
|
2- Exécuter :
|
||||||
|
$ java CBaP add.mvap.cbap
|
||||||
|
ou pour mieux comprendre avec des traces :
|
||||||
|
$ java CBaP -d add.mvap.cbap
|
||||||
|
|
||||||
|
|
||||||
|
** Pour construire le jar, il faut :
|
||||||
|
1- avoir un META-INF/MANIFEST pour inclure le jar antlr dans le CLASSPATH :
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Version: 2.1
|
||||||
|
Main-Class: CBaP
|
||||||
|
Class-Path: /usr/local/java/antlr-4.4-complete.jar
|
||||||
|
|
||||||
|
2- Contruire le jar avec :
|
||||||
|
$ jar cfm MVaP.jar META-INF/MANIFEST *.class
|
||||||
|
|
||||||
|
|
||||||
|
On peut aussi faire tout simplement :
|
||||||
|
$ make
|
||||||
|
|
||||||
|
** Utilisation du jar :
|
||||||
|
|
||||||
|
1- Assembler :
|
||||||
|
$ java -cp .:/usr/local/java/antlr-4.4-complete.jar:MVaP.jar MVaPAssembler add.mvap
|
||||||
|
|
||||||
|
2- Exécuter :
|
||||||
|
$ java -jar MVaP.jar -d add.mvap.cbap
|
BIN
MVaP/MVaP.jar
Normal file
BIN
MVaP/MVaP.jar
Normal file
Binary file not shown.
7
MVaP/add.mvap
Normal file
7
MVaP/add.mvap
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# calcule : 2 + 40
|
||||||
|
PUSHI 2
|
||||||
|
PUSHI 40
|
||||||
|
ADD
|
||||||
|
WRITE
|
||||||
|
POP
|
||||||
|
HALT
|
BIN
MVaP/add.mvap.cbap
Normal file
BIN
MVaP/add.mvap.cbap
Normal file
Binary file not shown.
BIN
MVaP/antlr-4.5.2-complete.jar
Normal file
BIN
MVaP/antlr-4.5.2-complete.jar
Normal file
Binary file not shown.
27
MVaP/test.mvap
Normal file
27
MVaP/test.mvap
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# On prend au départ 2
|
||||||
|
# on ajoute 3 et on élève le tout au carré
|
||||||
|
# on recommence et on s'arrête dès que l'on dépasse 100
|
||||||
|
PUSHI 2
|
||||||
|
LABEL 1
|
||||||
|
PUSHI 3
|
||||||
|
ADD
|
||||||
|
WRITE
|
||||||
|
CALL 2
|
||||||
|
WRITE
|
||||||
|
# a-t-on un sommet de pile < 100 ?
|
||||||
|
DUP
|
||||||
|
PUSHI 100
|
||||||
|
SUP
|
||||||
|
JUMPF 1
|
||||||
|
# le nombre affiché est plus grand que 100, on s'arrête
|
||||||
|
HALT
|
||||||
|
# procédure qui élève un nombre au carré
|
||||||
|
LABEL 2
|
||||||
|
# récupère le premier paramètre (-3 = -1 - 2)
|
||||||
|
PUSHL -3
|
||||||
|
DUP
|
||||||
|
MUL
|
||||||
|
# on a donc son carré en sommet de pile
|
||||||
|
STOREL -3
|
||||||
|
# on remplace la valeur
|
||||||
|
RETURN
|
BIN
MVaP/test.mvap.cbap
Normal file
BIN
MVaP/test.mvap.cbap
Normal file
Binary file not shown.
BIN
images/4-hierarchy.jpg
Normal file
BIN
images/4-hierarchy.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
BIN
images/MMU_principle_updated.png
Normal file
BIN
images/MMU_principle_updated.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
12902
images/Virtual_memory.svg
Normal file
12902
images/Virtual_memory.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 418 KiB |
Loading…
Reference in New Issue
Block a user