« Fonctionnement d'un ordinateur/Les jeux d'instructions » : différence entre les versions

Contenu supprimé Contenu ajouté
Ligne 21 :
|Mémoire FIFO/LIFO. Les opérandes et résultats sont placés dans une mémoire FIFO ou LIFO.
|}
 
===Architectures à pile et à file===
 
[[File:Exemple d'une machine à pile qui code ses entiers sur 4 Bytes.png|vignette|Exemple d'une pile/file d'opérandes, chaque opérande étant codée sur 4 Bytes.]]
 
Les premières architectures que nous allons voir sont les '''machines à pile''' et les '''machines à file''' des jeux d'instructions où les registres sont remplacés par une mémoire tampon dédiée aux opérandes de calculs. Il s'agit d'une mémoire de type FIFO pour une machine à file, alors que c'est une LIFO pour une machine à pile. La FIFO/LIFO est placée dans le processeur sur certaines machines, alors que d'autres la placent dans la mémoire RAM. Dans le premier cas, la mémoire tampon sert d'intermédiaire entre la mémoire RAM et le reste du processeur. Dans les deux cas, les opérandes sont stockées dans la mémoire tampon dans leur ordre d'ajout et chaque opérande prend exactement un byte, pas plus ni moins. Les opérandes sont chargées par certaines instructions dans la FIFO/LIFO et y sont placées les unes à la suite des autres. De plus, quand le processeur fait un calcul quelconque, le résultat est ajouté à la pile/file. La pile/file se remplit donc progressivement d'opérandes chargées volontairement ou de résultats de calculs. Les seules opérandes manipulables par une instruction sont placées au sommet de la pile ou file : il faut ajouter les opérandes unes par unes avant d'exécuter l'instruction. L'instruction dépile automatiquement les opérandes qu'elle utilise et empile son résultat.
 
[[File:Machines LIFO et FIFO.png|centre|vignette|upright=3.0|Machines LIFO et FIFO.]]
 
Sur certaines machines FIFO/LIFO, la pile et la file sont localisées non pas dans le processeur, mais dans la mémoire RAM. Ces machines ont besoin d'un registre pour stocker l'adresse du sommet de la pile/file. Dans le cas d'une machine à pile, celui-ci est appelée le stack pointer, ou '''pointeur de pile'''. Sur les machines à file, il est appelé le ''queue pointer'', ou encore le '''pointeur de file'''. Les instructions de calcul utilisent uniquement les registres de pile pour savoir où se trouvent les opérandes. En clair, toutes les instructions utilisent uniquement le mode d'adressage implicite. Il va de soit que pour simplifier la conception du processeur, celui-ci peut contenir des registres internes pour stocker temporairement les opérandes des calculs, mais ces registres ne sont pas accessibles au programmeur : ce ne sont pas des registres architecturaux. Par exemple, sur certaines machines à pile, tout ou partie de la pile est stockée directement dans des registres internes au processeur, pour gagner en performance.
 
====Les instructions des machines à pile/file====
 
Ces jeux d’instructions ont des instructions pour ajouter des opérandes dans la FIFO/LIFO ou en retirer. Dans ce qui va suivre, nous allons prendre l'exemple d'une machine à pile, mais il existe des équivalents pour les machines à file. Dans les grandes lignes, il y a deux instructions principales, une d'ajout et une de retrait, ainsi que quelques instructions annexes sur certaines machines.
 
Pour empiler une donnée, le processeur fourni une instruction PUSH qui prend l'adresse de la donnée à empiler, charge la donnée, et met à jour le stack pointer. L'instruction POP dépile la donnée au sommet de la pile, la stocke à l'adresse indiquée dans l'instruction, et met à jour le stack pointer.
 
{|class="wikitable"
|[[File:Instruction Push.png|Instruction Push.]]
|[[File:Instruction Pop.png|Instruction Pop.]]
|}
 
Vu qu'une instruction dépile ses opérandes, on ne peut pas les réutiliser. Ceci dit, certaines instructions ont été inventées pour limiter la casse : on peut notamment citer l'instruction DUP, qui copie le sommet de la pile en deux exemplaires. On peut aussi citer l'instruction SWAP, qui échange deux données dans la pile.
 
{|class="wikitable"
|[[File:Instruction Dup.png|Instruction Dup.]]
|[[File:Instruction Swap.png|Instruction Swap.]]
|}
 
Les machines à pile que je viens de décrire ne peuvent manipuler que des données sur la pile : ces machines à pile sont ce qu'on appelle des '''machines à zéro adresse'''. Avec une telle architecture, les instructions sont très petites, car il n'y a pas besoin de bits pour indiquer la localisation des données dans la mémoire, sauf pour POP et PUSH. Toutefois, certaines machines à pile plus évoluées autorisent certaines instructions à préciser l'adresse mémoire d'un (voire plusieurs, dans certains cas) de leurs opérandes. Ces machines sont appelées des '''machines à pile à une adresse'''.
 
====Avantages et désavantages====
 
Sur ces architectures, les programmes utilisent peu de mémoire. La raison à cela est que les instructions sont très petites : on n'a pas besoin d'utiliser de bits pour indiquer la localisation des données dans la mémoire, sauf pour Pop et Push. Vu que les programmes crées pour ces machines sont souvent très petits, on dit que la code density (la densité du code) est bonne. Par contre, une bonne partie des instructions de notre programmes seront des instructions Pop et Push qui ne servent qu'à déplacer les opérandes entre la RAM et la FIFO/LIFO. Une bonne partie des instructions ne sert donc qu'à manipuler la mémoire et pas à faire des calculs. Sans compter que notre programme comprendra beaucoup d'instructions comparé aux autres types de processeurs. Enfin, ces machines n'ont pas besoin d'utiliser beaucoup de registres pour stocker leur état : un Stack Pointer et un Program Counter suffisent. Les machines à pile furent les premières à être inventées et utilisées : dans les débuts de l’informatique, la mémoire était rare et chère, et l'économiser était important. Ces machines à pile permettaient d'économiser de la mémoire facilement et d'utiliser peu de registres, ce qui était le compromis idéal pour l'époque.
 
Les architectures à pile et à file ont plusieurs défauts. En premier lieu, la complexité de la gestion de la pile/file entraine l'usage d'un grand nombre d'instructions d'accès mémoire. Mais surtout, il est impossible de réutiliser une donnée chargée dans la pile, toute opération dépilant ses opérandes. Cela entraine un grand nombre d'accès en mémoire RAM, défaut rédhibitoire quand la RAM est lente et peu chère et où la hiérarchie mémoire dicte sa loi. Les autres classes d'architectures n'ont pas ces défauts et font usage de modes d'adressage autres que le mode d'adressage implicite. L'usage de ces modes d'adressages permet d'éviter d'avoir à copier des données dans une pile, les empiler, et les déplacer avant de les manipuler. Le nombre d'accès à la mémoire est donc plus faible comparé à une machine à pile pure.
 
===Architecture mémoire-mémoire===
Ligne 93 ⟶ 57 :
 
[[File:Isreg2reg.png|centre|Architecture LOAD-STORE.]]
 
 
===Architectures à pile et à file===
 
[[File:Exemple d'une machine à pile qui code ses entiers sur 4 Bytes.png|vignette|Exemple d'une pile/file d'opérandes, chaque opérande étant codée sur 4 Bytes.]]
 
Les premièresdernières architectures que nous allons voir sont les '''machines à pile''' et les '''machines à file''' des jeux d'instructions où les registres sont remplacés par une mémoire tampon dédiée aux opérandes de calculs. Il s'agit d'une mémoire de type FIFO pour une machine à file, alors que c'est une LIFO pour une machine à pile. La FIFO/LIFO est placée dans le processeur sur certaines machines, alors que d'autres la placent dans la mémoire RAM. Dans le premier cas, la mémoire tampon sert d'intermédiaire entre la mémoire RAM et le reste du processeur. Dans les deux cas, les opérandes sont stockées dans la mémoire tampon dans leur ordre d'ajout et chaque opérande prend exactement un byte, pas plus ni moins. Les opérandes sont chargées par certaines instructions dans la FIFO/LIFO et y sont placées les unes à la suite des autres. De plus, quand le processeur fait un calcul quelconque, le résultat est ajouté à la pile/file. La pile/file se remplit donc progressivement d'opérandes chargées volontairement ou de résultats de calculs. Les seules opérandes manipulables par une instruction sont placées au sommet de la pile ou file : il faut ajouter les opérandes unes par unes avant d'exécuter l'instruction. L'instruction dépile automatiquement les opérandes qu'elle utilise et empile son résultat.
 
[[File:Machines LIFO et FIFO.png|centre|vignette|upright=3.0|Machines LIFO et FIFO.]]
 
Sur certaines machines FIFO/LIFO, la pile et la file sont localisées non pas dans le processeur, mais dans la mémoire RAM. Ces machines ont besoin d'un registre pour stocker l'adresse du sommet de la pile/file. Dans le cas d'une machine à pile, celui-ci est appelée le stack pointer, ou '''pointeur de pile'''. Sur les machines à file, il est appelé le ''queue pointer'', ou encore le '''pointeur de file'''. Les instructions de calcul utilisent uniquement les registres de pile pour savoir où se trouvent les opérandes. En clair, toutes les instructions utilisent uniquement le mode d'adressage implicite. Il va de soit que pour simplifier la conception du processeur, celui-ci peut contenir des registres internes pour stocker temporairement les opérandes des calculs, mais ces registres ne sont pas accessibles au programmeur : ce ne sont pas des registres architecturaux. Par exemple, sur certaines machines à pile, tout ou partie de la pile est stockée directement dans des registres internes au processeur, pour gagner en performance.
 
====Les instructions des machines à pile/file====
 
Ces jeux d’instructions ont des instructions pour ajouter des opérandes dans la FIFO/LIFO ou en retirer. Dans ce qui va suivre, nous allons prendre l'exemple d'une machine à pile, mais il existe des équivalents pour les machines à file. Dans les grandes lignes, il y a deux instructions principales, une d'ajout et une de retrait, ainsi que quelques instructions annexes sur certaines machines.
 
Pour empiler une donnée, le processeur fourni une instruction PUSH qui prend l'adresse de la donnée à empiler, charge la donnée, et met à jour le stack pointer. L'instruction POP dépile la donnée au sommet de la pile, la stocke à l'adresse indiquée dans l'instruction, et met à jour le stack pointer.
 
{|class="wikitable"
|[[File:Instruction Push.png|Instruction Push.]]
|[[File:Instruction Pop.png|Instruction Pop.]]
|}
 
Vu qu'une instruction dépile ses opérandes, on ne peut pas les réutiliser. Ceci dit, certaines instructions ont été inventées pour limiter la casse : on peut notamment citer l'instruction DUP, qui copie le sommet de la pile en deux exemplaires. On peut aussi citer l'instruction SWAP, qui échange deux données dans la pile.
 
{|class="wikitable"
|[[File:Instruction Dup.png|Instruction Dup.]]
|[[File:Instruction Swap.png|Instruction Swap.]]
|}
 
Les machines à pile que je viens de décrire ne peuvent manipuler que des données sur la pile : ces machines à pile sont ce qu'on appelle des '''machines à zéro adresse'''. Avec une telle architecture, les instructions sont très petites, car il n'y a pas besoin de bits pour indiquer la localisation des données dans la mémoire, sauf pour POP et PUSH. Toutefois, certaines machines à pile plus évoluées autorisent certaines instructions à préciser l'adresse mémoire d'un (voire plusieurs, dans certains cas) de leurs opérandes. Ces machines sont appelées des '''machines à pile à une adresse'''.
 
====Avantages et désavantages====
 
Sur ces architectures, les programmes utilisent peu de mémoire. La raison à cela est que les instructions sont très petites : on n'a pas besoin d'utiliser de bits pour indiquer la localisation des données dans la mémoire, sauf pour Pop et Push. Vu que les programmes crées pour ces machines sont souvent très petits, on dit que la code density (la densité du code) est bonne. Par contre, une bonne partie des instructions de notre programmes seront des instructions Pop et Push qui ne servent qu'à déplacer les opérandes entre la RAM et la FIFO/LIFO. Une bonne partie des instructions ne sert donc qu'à manipuler la mémoire et pas à faire des calculs. Sans compter que notre programme comprendra beaucoup d'instructions comparé aux autres types de processeurs. Enfin, ces machines n'ont pas besoin d'utiliser beaucoup de registres pour stocker leur état : un Stack Pointer et un Program Counter suffisent. Les machines à pile furent les premières à être inventées et utilisées : dans les débuts de l’informatique, la mémoire était rare et chère, et l'économiser était important. Ces machines à pile permettaient d'économiser de la mémoire facilement et d'utiliser peu de registres, ce qui était le compromis idéal pour l'époque.
 
Les architectures à pile et à file ont plusieurs défauts. En premier lieu, la complexité de la gestion de la pile/file entraine l'usage d'un grand nombre d'instructions d'accès mémoire. Mais surtout, il est impossible de réutiliser une donnée chargée dans la pile, toute opération dépilant ses opérandes. Cela entraine un grand nombre d'accès en mémoire RAM, défaut rédhibitoire quand la RAM est lente et peu chère et où la hiérarchie mémoire dicte sa loi. Les autres classes d'architectures n'ont pas ces défauts et font usage de modes d'adressage autres que le mode d'adressage implicite. L'usage de ces modes d'adressages permet d'éviter d'avoir à copier des données dans une pile, les empiler, et les déplacer avant de les manipuler. Le nombre d'accès à la mémoire est donc plus faible comparé à une machine à pile pure.
 
==RISC vs CISC==