Assembleur Intel avec NASM


précédentsommairesuivant

IV. Assembleur : des graphiques !

49 commentaires Donner une note à l'article (5)

Relu par ClaudeLELOUP.

Aux dernières nouvelles, nous en étions à lire des choses au clavier et à regarder un peu ce qu'il y a dans la machine. C'est bien. On peut mieux. On peut mieux comment ? Allez, si on mettait à profit l'extraordinaire capacité de l'ordinateur à faire de l'affichage ?

IV.1. De Windows Vista

Je ne veux pas être mauvaise langue, mais Windows Vista, entre nous soit dit, ce n'est pas fabuleux. On ne pourra plus exécuter notre programme sous Vista, parce que Môssieur Vista a décidé que non, c'était pas bien d'accéder au BIOS, surtout pour faire de l'affichage. Si bien que quand on va appeler une certaine fonction du gestionnaire d'affichage du BIOS (la fonction du pilote VESA), on va se faire jeter comme des malpropres. Ce n'est pas chouette de sa part, alors on va ruser : DOSBOX est un émulateur DOS qui fonctionne sous Vista.

Doit-on considérer qu'on est mauvais si on se fait renvoyer dans nos 6 mètres par Vista ? Je ne crois pas : VESA est un standard, je ne vois pas pourquoi on n'aurait pas le droit de l'utiliser.

Pour nous enquiquiner encore plus, NASM ne fonctionne pas avec DOSBOX. Donc, deux fenêtres : une en cmd normal, et une de DOSBOX. Je VEUX y arriver, et c'est pas Kro$oft qui va me l'interdire !

IV.2. Le refacteur sonne toujours une paire de fois (refactoring)

Quand le code évolue, on change des trucs et des machins. On refait d'autres trucs. "Cent fois sur le métier remets ton ouvrage", disait Penelope Cruz, à moins que je n'aie pas tout saisi (note du correcteur : ça doit remuer dans les allées du Père Lachaise. Pauvre Boileau !). J'ai amélioré la fonction d'écriture de texte, histoire qu'on n'écrive pas n'importe où : quand on a plus de 80 caractères à afficher, elle faisait un peu n'importe quoi. Mais pas que. Une nouvelle instruction a fait son apparition : LODSB, comme LOaD String Byte. C'est l'équivalent de MOV [DS:SI], AL INC SI. Et pour être cohérent, plus facile à utiliser, l'adresse de la chaîne à afficher se passe maintenant dans le registre SI (Source Index) pour son offset, et DS (Data Segment) pour son segment.

J'ai mis la lecture au clavier dans une fonction, ça aura l'avantage de pouvoir être appelé n'importe quand, et donc de servir d'arrêt dans l'exécution du programme, ah là là, je suis d'une fourberie sans nom. Là aussi, une nouvelle fonction a fait son apparition : STOSB, comme STOre String Byte. Exactement l'inverse de LOSB, mais avec des registres différents : DI (Destination Index) comme offset d'adresse et ES (Extra Segment) comme segment d'adresse. Instructions équivalentes : MOV AL, [ES:DI] INC DI. Donc, on passe l'adresse de la chaîne de destination dans ces registres.

La fonction d'affichage de nombres a subi elle aussi une cure de jouvence : on peut, pensez donc, afficher des nombres jusqu'à 65535 ! Elle prend d'autres paramètres, comme BL, dont le bit de poids faible est mis à un si on veut terminer la chaîne de caractères à la fin, et BH, qui donne le nombre minimal de caractères que doit contenir la chaîne écrite. Ah oui. J'oubliais. Cette fonction transforme AX en chaîne de caractères. Elle ne l'affiche pas.

Il paraît que refaire des choses, comme cela, s'appelle du refactoring. C'est un bien vilain mot qui écorche l'oreille fine du franchouillard : recodage serait mieux, de mon point de vue.

IV.3. De VESA

Au commencement était la carte perforée. Puis vint la télévision. Ou inversement. Bref, les ordinateurs furent munis d'un écran. Monochrome. Puis on sut écrire autre chose que du texte. Puis apparut le niveau de gris, puis la couleur. Puis tout le monde fit n'importe quoi. IBM sortit alors la spécification VGA. On progressa encore. Ce fut pire. Re standard, et VESA.

VESA est, succinctement, le pilote des cartes graphiques au-delà de VGA. Pour savoir s'il est disponible, une interruption : 0x10 (puisque c'est du gestionnaire vidéo), une fonction : 0x4F, et une tripotée de sous-fonctions. L'idée est d'appeler la sous-fonction 0x00 qui va nous dire tellement de choses que bien des tortionnaires envieraient la place du développeur.

A cette sous-fonction, il faut lui donner un espace mémoire pour qu'elle puisse y mettre toutes ces choses qu'elle sait. Elle va les mettre à l'adresse contenue dans le registre DI (comme Destination Index), et elle a besoin de 256 octets. Nous allons lui donner entière satisfaction, puisque nous allons lui donner notre adresse fourre-tout, à savoir le label hello. On dispose d'au moins 16 ko de mémoire, donc on a de la place en bout de programme pour stocker 256 octets, on ne s'occupe de rien en ce moment.

Comme nous sommes des fous parfaitement au fait du fonctionnement d'un microprocesseur, on colle directement les paramètres dans AX en une seule instruction, ah oui madame, je suis un malade des cycles d'horloge, c'est précieux ces choses-là.

Voici la structure de ce qui nous est renvoyé :

Offset Taille Description
0x00 4 octets (Double Mot) Signature, doit contenir la chaîne de caractères "VESA".
0x04 2 octets (Mot) Numéro de version du VESA. AH : numéro majeur. AL : numéro mineur.
0x06 4 octets (Double Mot) Pointeur sur le nom de l'OEM terminé par un caractère NULL.
0x0A 4 octets (Double Mot) Ca, je n'ai pas compris.
0x0E 4 octets (Double Mot) Pointeur sur une liste de modes vidéo du VESA supportés par l'OEM. Se termine par le code 0xFFFF. Chaque mode est stocké comme un mot.
0x11 238 octets Ca, je n'ai pas compris.

Nous allons lire et afficher tous les mots (mot veut dire nombre de 16 bits ici) tant qu'on ne lit pas le nombre magique 0xFFFF. Bon, d'accord, c'est beaucoup d'efforts pour pas grand-chose, puisque après, on se mettra dans le mode 0x13. Mais on sera prêts pour la suite.

IV.4. Du point

Ensuite, on est parti pour l'affichage d'un point. Ca consiste en l'écriture dans la mémoire vidéo d'une couleur. Une couleur, en mode 0x13, c'est un octet. Les coordonnées en abscisse et ordonnée du point à afficher doivent être transformées en coordonnée linéaire, la mémoire étant linéaire. Pour ce faire, la formule est : ordonnée * nombre de points sur la ligne + abscisse. Subtilité : plutôt que de faire une multiplication par 320, on travaille par deux décalages de bits (multiplication par puissances de 2) additionnés. On écrit à cette coordonnée linéaire la valeur de la couleur, et c'est fait.

IV.5. De Bresenham

Maintenant, tracer des lignes. Des segments de droite, pour être exact. Il nous faut un algorithme, c'est-à-dire la marche à suivre pour parvenir à nos fins. Wikipédia nous en fournit un, qui est le top des algorithmes de tracé de segment : l'algorithme de Bresenham

Cet algorithme, il faut le traduire en assembleur. Ma traduction n'est certainement pas fabuleuse, mais aux dernières nouvelles, elle fonctionne.

IV.6. Du code

Le code de ce chapitre se trouve ici : carabistouille.asm. Parce que bon, ça commence à faire de la ligne de code.


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2011 Etienne Sauvage. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.