|
HPGrâal Numero 1
INITIATION A L'ASSEMBLEUR
Premier numéro d'HPGrâal, et première leçon d'ASM ... C'est le début d'une longue série ! L'objectif final étant que vous soyez aussi bon que moi (si c'est possible :) )...
Bon on va peut-être commencer ? Alors sortez vos cahiers, respirez à fond, et nous voila partis dans les profondeurs du Saturn (que la Force soit avec vous !).
- L'assembleur c'est quoi ?
- L'assembleur est un langage de programmation, comme le RPL ou l'External (beurk !), qui permet d'accéder directement au coeur de votre HP pour lui faire faire ce que vous voulez, et en plus à une vitesse folle (près de 1000 fois plus rapide que le RPL)...
- Mais comment est-ce possible ? eh bien tout simplement en contrôlant directement le processeur... Vous savez, ce truc électronique qu'on compare souvent au "cerveau" des ordinateurs ou des calculatrices, qui contrôle tous leurs périphériques (mémoire, écran, clavier, etc...), et qui fait marcher la machine... C'est à lui qu'on va s'attaquer dans ce numéro.
- Un peu d'électronique.
- Les flèches indiquent le sens des relations entre les différents constituants de la
HP .
- Comme dans toutes les machines de Van Neuwman, la mémoire contient des données et des programmes. Le processeur contient deux circuits électroniques : l'unité de contrôle lit en mémoire les programmes, et reconnaît les différentes instructions du processeur. L'unité de traitement exécute ces instructions dans le but de traiter les informations. Elle peut lire et écrire des données en mémoire. Pour travailler, elle utilise des registres, sortes de mini-mémoires qui servent à stocker des informations temporaires.
- Le binaire et les bits.
- L'informatique utilise beaucoup l'électronique, ce qui explique l'utilisation du binaire : un interrupteur peut être dans deux états : ouvert ou fermé, ce qu'on traduit mathématiquement par 0 ou 1. Ainsi, on code tout en binaire (textes, images, chiffres, programmes, sons...). C'est très pratique pour les nombres : on utilise la base 2 ce qui permet de faire faire des opérations mathématiques au processeur (sur
HP : additions et soustractions).
- On appelle alors "bit" la plus petite quantité d'information (pour BInary digiT). Un bit vaut 0 ou 1.
- Le processeur de la
HP est un Saturn, qui rentre dans la classe des processeurs 4 bits, ce qui signifie qu'il analyse les informations par blocs de 4 bits, appelés "quartets". En informatique, pour mesurer les capacités de mémoire, on utilise plutôt l'octet : un octet = 8 bits = 2 quartets.
A noter : 1 Ko (Kilo-octet) = 1024 octets = 210 octets
1 Mo (Mega-octet) = 1024 Kilo-octets = 220 octets
- On parle aussi de Go (Giga-octets) mais pas sur
HP .
- Compter en base binaire.
- Je vous renvoie à vos cours de maths de CM2 pour savoir ce qu'est une base. [ndJCL : Cela fait longtemps que les bases ont été virées des programmes de primaire... Et d'ailleurs, cela était plus ou moins fait selon le niveau en math des instits...]. Comme je suis gentil et que je sais que vous êtes aussi fainéants que moi, voici un exemple :
base | décimale | binaire | hexadécimale (base 16)
nombres | 0 | 0 | 0
| 1 | 1 | 1
| 2 | 10 | 2
| 3 | 11 | 3
| 4 | 100 | 4
| 5 | 101 | 5
| 6 | 110 | 6
| 7 | 111 | 7
| 8 | 1000 | 8
| 9 | 1001 | 9
| 10 | 1010 | A
| 11 | 1011 | B
| 12 | 1100 | C
| 13 | 1101 | D
| 14 | 1110 | E
| 15 | 1111 | F
| 16 | 10000 | 10
- Bon allez, je suis sympa alors j'explique : 11 = 1*23 + 0*22 + 1*21 + 1*20 => 1011.
- [ndJCL: Vous pourrez remarquer que c'est exactement pareil qu'en base décimale, la base usuelle. En effet, 1798 = 1*103 + 7*102 + 9*101+ 8*100 ]
- Vous remarquez tout de suite que pour multiplier par deux un nombre en binaire, il suffit de rajouter un 0 à la fin !
- Sur
HP , on utilise surtout l'hexadécimal, très pratique puisque sur un quartet on peut coder 16 chiffres...
- [ndJCL: Un peu faible l'argument! On utilise surtout l'hexadécimal car la traduction hexa <----> binaire est très simple; en effet, il suffit de regrouper par 4 les chiffres binaires, de les traduire en hexa par groupe de 4 et de mettre le tout bout à bout pour obtenir de l'hexa; et de traduire chaque chiffre hexa en binaire et de mettre bout à bout pour obtenir du binaire. Ainsi:
C <----> 1100
8 <----> 1000
C8 <----> 11001000
- Tout cela est du au fait que 16 est une puissance de 2]
- Les différents langages.
- On a vu tout à l'heure que le processeur reconnaissait les instructions qu'il lit en mémoire par l'intermédiaire de l'unité de contrôle. En fait à chaque instruction réalisable par le Saturn est associé au moins un code binaire (ou hexadécimal, c'est pareil). Par exemple, la séquence
101010100110 (AA6 en hexadécimal) est interprétée par l'unité de contrôle du Saturn comme "multiplie par deux le contenu de telle partie de tel registre".
- On appelle Langage Machine l'ensemble des codes binaires connus par le processeur.
- Mais nous le binaire (et même l'hexadécimal) on aime pas trop parce que c'est pas très parlant. Alors au lieu de se prendre la tête à programmer avec des
0 et des 1 , on utilise l'assembleur : à chaque instruction du langage machine, on associe un mnémonique plus agréable à utiliser. Pour reprendre l'exemple de tout à l'heure, au lieu de "101010100110 " on utilise plutôt "C=C+C A ". C'est quand même plus pratique, non ? Bon OK il faut aussi savoir ce que ça veut dire, mais ça, ça viendra tout seul plus tard.
- Maintenant on a un problème : le langage machine est par définition le seul que comprenne la machine, donc le Saturn ne pige rien aux mnémoniques de l'assembleur, alors quand on a fait un programme en assembleur (qu'on abrégera en
ASM ), il faut traduire les mnémoniques pour obtenir du langage machine. Pour ça on utilise un programme (on va pas faire ça à la main, oh ! Pas fou non ?). Ce programme porte le même nom que le langage : on parle donc d'UN assembleur pour le programme et de L'assembleur pour le langage.
- Et le
RPL et l'External dans tout ça ? bah le RPL fait en fait appel à des sous programmes en Externals, eux-mêmes faisant appel à des programmes en langage machine. La lenteur de ces langages par rapport à l'assembleur est due à une plus grande complexité et aussi, il faut bien le reconnaître, à la mauvaise qualité des programmes internes de la HP .
- Comment on fait ?
- Dans ce numéro (et dans les suivants aussi) vous aller trouver un programme en assembleur (asm-pratik). Même si vous ne pouvez pas encore le comprendre vous pouvez quand même vous y intéresser, ça vous donnera une bonne idée de ce qu'est l'assembleur plus précisément... Je vais donc maintenant vous expliquer comment le rentrer dans votre
HP (valable pour tous les progs en ASM ) :
- Procurez-vous tout d'abord un assembleur : sur
S(x) je vous conseille Asm-flash dont j'utiliserai la syntaxe, comme tout le monde, car tous les assembleurs de la G(x) (ou presque) l'ont adoptée... donc prenez le premier qui vous tombe sous la main. Si toutefois vous voulez le Top du Top, ruez-vous sur le MASD du MétaKernel (Hpmâd) ou sur JASM (Jylog) (cf. news).
- Ensuite recopiez le programme dans une chaîne de caractères en respectant les sauts de lignes après chaque instruction et sans oublier le caractère
@ (alpha, shift-droit et ENTER) à la fin. Par contre vous n'êtes pas obligés de mettre les commentaires (signalés par un % ), mais vous pouvez, ils ne seront pas assemblés. On appelle cette chaîne "source" du programme, sauvez-la pour pouvoir la modifier après...
- Puis rappelez-la au niveau 1 de la pile, et lancez votre assembleur. S'il n'y a pas d'erreurs dans la source (personne n'est parfait), vous devriez obtenir un objet "code" : c'est votre programme, faites en ce que vous vous voulez...
- Petit (gros) conseil : lorsque vous ferrez vos programmes vous mêmes, sauvegardez toujours ce que vous avez de précieux sur ordinateur ou carte protégée en écriture, car un programme marche rarement du premier coups, et en assembleur, la moindre erreur (dites bug) provoque souvent un plantage de la
HP . En général, on s'en sort en appuyant sur ON et C en même temps, mais pas toujours. Dans ce cas il faut toujours avoir un trombone sur soi : insérez-le dans le trou sous le patin haut/droit au dos de la HP , ça la relancera, mais vous risquez de perdre le contenu de la mémoire (rassurez-vous ça n'arrive pas si souvent). Dernier détail : nos programmes sont (normalement) sans bugs...
- La structure de la machine
- Après tant de théorie, on va enfin s'attaquer à quelque chose de plus concret, en regardant de plus près la structure de la machine.
- On ne va pas tout de suite parler du Saturn, parce qu'il y a des choses que vous devez savoir avant. (ne soyez pas effrayés par la quantité d'informations que vous recevez...). On va donc voir maintenant la mémoire et les Entrées/Sorties.
- La mémoire.
- Il y en a de deux sortes : la mémoire
RAM et la ROM . ROM signifie en anglais "Read Only Memory" c'est-à-dire qu'on ne peut que lire cette mémoire et surtout pas y écrire. Ce type de mémoire sert à stocker les programmes qui font fonctionner votre machine : ceux qui ont étés écrits par Hewlett Packard. Cette mémoire ne peut pas bouger, ce qui assure la sécurité du système...
- La
RAM quant à elle, permet de stocker vos programmes ou vos données puisqu'on peut y écrire et y lire.
- Sur
HP , la ROM fait 512Ko et la RAM destinée aux utilisateurs fait 32 Ko pour les G et 128 Ko pour les GX .
- Mais dans la
HP , il y a aussi deux autres mémoires RAM , qui elles ne servent pas directement pour l'utilisateur, mais qui sont très pratiques pour les programmeurs : la RAM I/O et le Bank-Switcher.
- La RAM I/O.
- Ou
RAM des Entrées/Sorties. Cette mémoire sert d'intermédiaire entre le processeur et les périphériques (contrôleur d'écran, IR et câble, horloge), mais aussi avec d'autres composants de la machine, comme les piles ou le bus. En fait ce n'est pas une vraie mémoire RAM au sens ou certaines parties n'en sont pas lisibles et ne servent qu'en écriture à transmettre des informations aux périphériques. Certaines parties même ne servent pas à la même chose suivant qu'on y lise ou qu'on y écrive. On verra dans un autre numéro le détail de toutes ces parties et leurs rôles.
- Le Bank-Switcher.
- Ou Sélecteur de bancs. Cette mémoire sert à sélectionner le banc de la carte en port 2 des
HP48GX . Vous savez sûrement que sur GX on peut mettre des cartes de capacité supérieure à 128Ko en port 2. Pour gérer ces cartes, la HP les considère en fait comme plusieurs "bancs" de 128Ko chacun. En gros c'est comme si vous aviez plusieurs cartes de 128 Ko dans une seule. La HP ne peut travailler que sur un seul banc à la fois, il faut donc qu'elle puisse sélectionner le banc sur lequel elle va travailler : le Bank-Switcher sert à ça...
- Pour choisir un banc il suffit de lire quelque chose dans la partie du Bank-Switcher correspondante. Ce n'est donc pas une vrai mémoire, on parle plutôt de Module.
- A noter : ce module est présent sur les
HP48G , bien qu'elles ne puissent pas recevoir de cartes.
- Les entrées et sorties contrôlées par le processeur.
- Les entrées : seul le clavier est contrôlé par le processeur, on y reviendra.
- Les sorties : il n'y a que le beeper. Il est d'ailleurs contrôlé par les mêmes instructions que le clavier.
- Le bus.
- Ce bus là n'a rien à voir avec la
RATP . Il s'agit de l'organe de la HP qui permet aux différents éléments de communiquer avec le Saturn. Petit schéma :
- Lorsque le Saturn veut communiquer avec un des chips (modules) de la
HP , il envoie sur le bus une adresse (vous remarquerez qu'il y a 4 fils sur le bus : c'est un bus 4 bits), et en même temps un signal électrique dans la daisy-chain.
- Chaque module a un gestionnaire relié à la daisy-chain. Ainsi lorsqu'un gestionnaire reçoit un signal sur la daisy-chain il sait qu'il y a une adresse qui se balade sur le bus. Là il regarde si cette adresse le concerne ; si oui, il agit en conséquence, sinon il fait passer le message au gestionnaire suivant par la daisy-chain. La conséquence de ce système est une priorité des différents modules. Par exemple, la
RAM est prioritaire sur la ROM , car si une information concerne la RAM elle n'atteindra pas la ROM .
- Le système d'adressage.
- Vous avez peut être remarqué que la
ROM n'a pas de gestionnaire... C'est du au fait que pour le Saturn une adresse tient sur 5 quartets, en hexadécimal, ce qui fait FFFFF , soit 1048575 adresses possible. Et chaque adresse correspond à un quartet. Le Saturn peut donc adresser 1 048 575 quartets, soit 512 Ko... Or c'est justement la taille de la ROM !!! Il en résulte que si un message arrive jusqu'à la ROM , il la concerne forcément, donc pas besoin de gestionnaire.
- Une autre conséquence du fait que la
ROM occupe tout le domaine des adresses possibles pour le Saturn est que certaines parties de la ROM sont masquées par les autres modules (qui eux aussi doivent avoir une adresse).
- Pour savoir si une information qui circule sur le bus concerne son module, un gestionnaire doit être configuré, c'est-à-dire qu'il doit connaître l'adresse de début de son module et sa taille (à l'exception de la
RAM I/O qui à une taille fixe de 32 octets et dont seule l'adresse est configurable).
- Pour avoir accès aux parties cachées par d'autres modules, le Saturn doit déconfigurer ces modules ou les reconfigurer à une autre adresse ou à une autre taille. Lorsqu'un module est déconfiguré c'est comme s'il n'existait plus...
- Remarques :
- Même si un module n'est pas présent, son gestionnaire existe toujours et doit être configuré (généralement à une adresse inutilisée et à sa taille minimale).
- A part pour la
RAM I/O dont la taille est fixe, la taille d'un module doit être un multiple de 2Ko.
- En plus, l'adresse du début d'un module doit être un multiple de sa taille.
- Si on configure un module à une taille plus petite que sa taille réelle, on n'aura accès qu'à son début.
- Si on configure un module à une taille plus grande que sa taille réelle, tout se passe comme si on avait plusieurs copies du modules à la suite.
- Le Saturn.
- Je vous ai déjà parlé des registres, mais je vais y revenir : les registres sont de toutes petites mémoires (comparées à la taille de la
RAM ) qui servent à stocker des informations utilisées par le Saturn de manière temporaire, pour éviter d'avoir à utiliser la RAM , car le processeur met environ 1000 fois moins de temps pour récupérer des informations dans les registres que dans la RAM . Ces registres sont de deux types : les registres "normaux" et les flags (ou drapeaux en français). Ces derniers ont le même rôle que les drapeaux utilisateurs : ce sont des indicateurs d'état contenant un bit. Par exemple un flag peut servir à indiquer que le son est allumé (à 1) ou éteint (à 0).
- Dans le Saturn, on trouve des registres pour plusieurs usages différents. Il y a :
- Les registres de calcul
- Les registres de sauvegarde.
- Les pointeurs
- Les registres - drapeaux
- Les registres d'Entrée/Sortie
- Les registres de calcul.
- Il y en a quatre en tout et on les nomme respectivement A, B, C, et D. Ce sont des registres de 64 bits, ce qui fait 16 quartets pour chaque registre. Ils servent à faire tous les calculs et même d'autre choses c'est pourquoi ce sont les registres les plus utilisés.
- Je vous ai dit que ces registres avaient une taille de 16 quartets (numérotes de
#0 à #F ), mais ils ont une structure plus compliquée, car ils sont divisées en champs. Un champ est une partie du registre sur laquelle on peut travailler séparément sans toucher au reste du registre. Mais ne croyez pas pour autant que l'on puisse considérer qu'un champ fonctionne comme un registre isolé, car les différents champs d'un même registre peuvent se recouper. Vous comprendrez sûrement mieux avec un petit schéma :
\/ numéro du quartet en hexadécimal
F E D C B A 9 8 7 6 5 4 3 2 1 0
|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|
/\ représentation des bits (par des points)
- Ca, c'est l'ensemble d'un registre. Voyons maintenant les différents champs (ce sont les mêmes pour tous les registres de calcul et aussi pour les registres de sauvegarde).
- Les champs qui suivent sont liés à la représentation des réels dans la
HP : ils sont codés sur 16 quartets dont un pour le signe, 12 pour la mantisse et 3 pour la valeur de l'exposant. On a donc :
F E D C B A 9 8 7 6 5 4 3 2 1 0
|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|
| S | M | X |<-- champs
| | | XS | B |<-- autres
champs
- Les noms :
S pour Signe, M pour Mantisse, X pour eXponant (exposant en anglais), et XS pour eXponant Sign. Vous connaissez déjà B .
- Vous remarquerez que les champs
A et M se chevauchent, donc si vous travaillez sur M vous allez modifier la fin du champ A du même registre, mais pas le champ X . Mais il y a encore d'autres champs :
- C'était le dernier ! En Général on utilise une notation pour ne pas avoir à répéter "le champ
A du registre C " ou encore "C champ A " : on écrit "Ca " ou "C.A " au choix. [ndJCL: On trouve aussi "C[A] ", et prononcez de toutes façon C champ A ].
- Petit détail sur les registres de calcul : ils ne sont pas du tout équivalents : on ne peut pas effectuer les mêmes opérations sur tous les registres. Entre autre, Le registre
C est le registre roi : on peut faire toutes les opérations sur lui. Ensuite vient le registre A qui peut aussi faire beaucoup de chose mais moins. Quand aux registres B et D ils servent la plupart du temps à stocker des valeurs pendant qu'on bosse sur C et A . De plus, si une instruction nécessite deux registres (par exemple une addition), on est obligé d'en prendre deux consécutifs (dans l'ordre alphabétique), sauf pour C qui marche aussi avec A . Il en résulte que l'on ne peut pas additionner A et D .
- Les registres de sauvegarde.
- Il y en à 6 en tout, ils ont pour noms
R0 , R1 , R2 , R3 , R4 et RSTK . Commençons par la série des R0 à R4 . Ce sont des registres du même type que les registres de calcul (entre autres ils sont également coupés en champs) et dont le seul rôle est de sauvegarder le contenu des registres A et C (et donc des registres B et D par leur intermédiaire), car 4 registres de calculs, même séparés en champs, c'est parfois un peu juste pour stocker tout ce dont on a besoin, alors plutôt que d'aller écrire en mémoire RAM ce qui est très lent, on met les valeurs dont on se sert peu dans les registres de sauvegarde et on les récupère quand on en a besoin...
- Le dernier,
RSTK est totalement différent : il s'agit de la pile des retours (Return StaCK) du Saturn: Ce processeur est capable d'exécuter ce que l'on appelle des sous-programmes, c'est-à-dire des programmes en langage machine normaux mais qui se finissent par l'instruction RTN (ReTurN). Le principe est que le processeur, qui est en train d'exécuter un programme stocké à l'adresse A peut aller exécuter un programme à l'adresse B et revenir à l'adresse A après. Ca sert par exemple quand on a besoin d'effectuer plusieurs fois un même programme à des moments différents et qu'on a pas envie de le répéter.
- L'instruction qui permet de sauter vers un sous-programme est
GOSUB adresse-du-sous-programme. Ainsi si on a :
adresses instruction
A GOSUB B
C suite du programme
... ...
B instruction du sous-programme
D RTN
- Le Saturn va voir "
GOSUB B " alors il va aller à
l'adresse B et il va exécuter les instructions du sous-programme, jusqu'à ce qu'il tombe
sur l'instruction "RTN ". A ce moment là, il retourne à l'adresse C et continue la suite du programme. On peut se demander où le Saturn écrit l'adresse C pour savoir que c'est là qu'il faut retourner après le RTN ? Bah.. à votre avis ? Oui bien joué, dans le registre RSTK ! Celui-ci fait 160 bits soit plutôt 8 groupes de 5 quartets (puisque les adresses sont stockées sur 5 quartets). On peut donc stocker 8 adresses dans cette pile ce qui permet d'emboîter jusqu'à 8 sous-programmes. En fait il est fortement déconseillé d'en emboîter plus de 6... Cette pile fonctionne comme celle de la HP : la dernière adresse rentrée est la première accessible
(et la seule !). Quand on y rentre une nouvelle adresse (ce qui est fait automatiquement par l'instruction GOSUB ), toutes les autres sont décalées, ce qui fait que la dernière est perdue (Eh oui contrairement à la pile dans laquelle vous faites vos calculs celle ci à une taille limitée, et lorsqu'elle est vide, elle ne comporte que des 0...).
- Cette utilisation explique qu'on se serve rarement de cette pile pour sauvegarder des données.
Il est tard maintenant et vous avez déjà bien travaillé alors on verra la suite des registres dans le prochains numéro, ainsi que les instructions dont on dispose pour programmer en ASM ...
HpFool
Des questions:hpgraal@hotmail.com
Un mot au WEBMASTER?:gissehel@mygale.org
Passez donc sur pulsar:Le site pulsar
|