ARTICLES
68 / 74 |
Cours sur l'assembleur Z80 - Premiers pas avec WINAPE
COURS D’ASSEMBLEUR - Premiers pas avec WINAPE
Winape est un très bon émulateur de CPC sous Windows. Mais il possède en plus quelques fonctions intéressantes comme... un assembleur ! En effet, ce logiciel permet d’écrire simplement des programmes en assembleur, puis de les compiler (c’est à dire les transformer en code machine compréhensible par le microprocesseur) directement en mémoire. Et, ô magie !, ils sont ensuite exécutables par un simple CALL sous l’écran BASIC (voir ci-dessous).
On peut trouver cet émulateur, dans sa version 2.0 alpha 18 dans la page Les Emulateurs
Mais attention, pour bénéficier du clavier AZERTY et des caractères français sous l’écran BASIC, il faut en plus la ROM française. Toutefois l’assembleur s’utilise normalement, c’est à dire avec le clavier PC.
L’assembleur de Winape est directement accessible avec la touche F6 (du clavier PC, pas du CPC). Une fenêtre apparaît alors, avec la gestion de fichier pour les sauvegardes, l’édition de texte, la compilation puis l’aide.
L’assembleur de WINAPE est compatible MAXAM 1.5 (un célèbre assembleur CPC). Il en possède donc les directives de compilation.
Les directives de compilation sont des instructions propre au compilateur. Ici ce sont celles de MAXAM, donc attention :
TOUS LES PROGRAMMES ECRITS EN ASSEMBLEUR POUR LE CPC NE FONCTIONNERONT PAS FORCEMMENT SOUS WINAPE SANS UNE CERTAINE ADAPTATION .
Ceci peut se vérifier notamment avec la notation hexadécimale. Sous WINAPE/MAXAM, elle est notée par exemple &FF ou #FF pour le nombre hexadécimal FF (255 en décimal). Mais certains programmes ont utilisé la notation 0FFh, avec un 0 devant et un h derrière donc. Ces programmes doivent alors être adaptés pour tourner sous WINAPE.
Toutefois, les directives sont généralement cohérentes d’un compilateur à un autre et les exemples que celui là sont peu nombreux.
Cette instruction, contrairement à ce que certains pensent, ne sert pas à définir l’adresse de début du programme compilé, mais l’adresse de la prochaine instruction compilée. En effet, rien n’empêche de l’utiliser plusieurs fois au court d’un programme (pour fixer l’adresse de fonctions par exemple).
ORG &4000
DB &FF
Une fois compilé, le programme placera l’octet &FF à l’adresse mémoire &4000. Voir ci-dessous pour l’instruction DB. Autre exemple :
DEBUT EQU &4000
ORG DEBUT
DB &FF
La directive EQU permettant de remplacer un nombre par une expression, on aura toujours notre octet &FF placé à l’adresse &4000. Et enfin :
FONCTION1 EQU &4000
FONCTION2 EQU &4002
ORG FONCTION1
DB &FF
ORG FONCTION2
DB &FF
Place &FF aux adresse &4000 et &4002. Il n’y aura rien en &4001, mais le programme aura bien une longueur de 3 octets quand même.
Il existe aussi la directive :
ORG expression1 , expression2
Permet de stocker le programme à l’adresse indiquée par expression2, mais de l’exécuter à l’adresse indiquée par expression1. Le programme pourra ensuite être sauvegardé à partir de la 2ème adresse, mais le programme aura quand même été compilé avec la 1ère adresse comme référence. Cette astuce, inutile aujourd’hui avec WINAPE, permettait de charger MAXAM en mémoire CPC sans occuper l’emplacement réel du programme compilé.
Permet de limiter la taille d’un programme (pour qu’il n’écrase pas la zone suivante par exemple). Si le programme dépasse, le compilateur indique une erreur.
LIMIT 100
Le programme ne pourra pas dépasser 100 octets.
Permettent (CODE) ou ne permettent pas (NOCODE) de compiler le code suivant l’expression. Ceci peut servir à occulter certaines parties du programme qui seraient fausses ou incomplètes, mais en permettant de tester le reste.
Le compilateur s’arrête quand il rencontre cette expression.
Les nombres sont notés de la manière suivante :
Décimal : 255
Hexadécimal : &FF ou #FF (préférez toutefois &FF)
Binaire : %11111111
Les caractères : ‘a’ ou ‘’a’’. Dans ce cas pour ‘’ on utilisera les apostrophes (‘ ‘’ ‘) et pour les apostrophes on utilisera les guillemets (‘’ ‘ ‘’).
Les phrases : "CPC6128", entre guillemets donc.
Les opérateurs arithmétiques : +,-,*,/,MOD (Comme en basic)
Les opérateurs logiques (à ne pas confondre avec les mnémoniques Z80) : AND, OR, XOR
Permet de pointer un endroit dans le programme, pour pouvoir y faire des sauts ou pour récupérer des données.
ORG &4000
Ld hl,DATA
Ld a,(hl)
...
DATA DB &FF
Quelque soit l’emplacement de DATA dans le programme, hl sera chargé avec son adresse. Puis l’accumulateur A sera chargé avec le contenu de cette adresse, soit &FF.
jp SAUT
...
SAUT ld a,(hl)
L’instruction jp saute à l’adresse indiquée par SAUT.
Cette directive entrevue plus haut, permet de remplacer un nombre par une expression.
DATA EQU &4000
Ld hl,DATA ; HL contiendra le nombre hexadécimal &4000
Comme nous l’avons vu avec la directive DB, il est possible de réserver un emplacement mémoire dans le programme, pour y placer des données prédéfinies ou non
DB (define BYTE) : Permet de remplir la mémoire avec des octets
DATA DB &FF, "a", 0, "COUCOU"
À l’emplacement mémoire DATA, DB a permis le stockage du nombre &FF, puis du nombre représenté par le code ascii de ‘a’, puis le nombre 0, puis des nombres représentés par les codes ascii de la chaîne "COUCOU".
Cette directive peut aussi être remplacée par les expressions BYTE, TEXT, DEFB et DEFM, moins utilisées cependant.
DW (define WORD): Permet de remplir la mémoire avec des “mots” binaires, c’est à dire des nombres de 16 bits.
DATA DW &4000, 15200, %1001110100001111
Attention, chaque donnée prenant 2 octets, il faudra incrémenter de 2 le registre servant d’indexage pour aller les chercher en mémoire.
Cette expression peut aussi être remplacée par DEFW ou WORD, moins utilisés cependant.
DS (define string) : Permet de réserver un bloc mémoire.
DATA DS 10
Réserve 10 octets à partir de l’adresse de DATA
DATA DS 10,&FF
Réserve 10 octets et les initialise tous à &FF. On aura alors 10 &FF à partir de l’adresse de DATA.
Il est possible d’assembler un programme en fonction d’une condition ou d’un numéro de version.
CPC464 EQU 0
CPC664 EQU 0
CPC6128 EQU 1
IF CPC464
Bloc programme pour le CPC464
ELSE : IF CPC664
Bloc programme pour le CPC664
ELSE
Bloc programme pour le CPC6128
ENDIF
ENDIF
En fait, l’expression après le IF est considérée comme un nombre de 16 bits. La condition est vraie s’il est strictement positif (&0001 à &7FFF), et fausse sinon (&0000 ou &8000 à &FFFF).
Pour mieux s’y retrouver quand on écrit un programme, il est préférable de bien le commenter. C’est encore plus vrai si quelqu’un doit passer derrière pour relire. Les commentaires ne sont jamais compilés, on peut donc en mettre tant qu’on veut sans que ça augmente la taille du programme. Ils sont indiqués par un point virgule :
ORG &4000
; ******************************
; * Mon programme à moi *
; ******************************
ld hl,DATA ; HL pointe les données
...
On va donc dans l’assembleur et on tape le programme suivant :
; Programme permettant l’affichage d’une phrase
ORG &4000
LD HL,TEXTE ;HL pointe le début de phrase
BOUCLE LD A, (HL) ;A
OR A ;A
RET Z ;retour de programme si A = 0
CALL &BB5A ;vecteur d’affichage d’un caractère
INC HL ;HL pointe le caractère suivant
JR BOUCLE ;revient à BOUCLE
TEXTE DB "AMSTRAD CPC",0
Ce programme commence par faire pointer HL sur le début de la phrase étiquetée par TEXTE, soit le 1er A.
Puis on forme une boucle qui lira tous les caractères de la phrase, jusqu’à ce que le nombre 0 soit détecté (celui qui se trouve après l’expression ‘’AMSTRAD CPC’’). Pour cela, on place le caractère courant dans A, puis on fait un masque OU avec lui même. Sachant que les codes ASCII contenus dans la phrase sont forcément différents de 0, ils contiennent donc au moins un 1 binaire. Ce qui fait que le OU entraînera alors la mise à 0 du flag Z (1 si détection de 0). L’instruction RET Z permet de terminer le programme si Z = 1, donc tous les caractères seront lus. Le vecteur &BB5A permet ensuite d’afficher le caractère contenu dans A, donc avec la boucle il affichera toute la phrase. HL est ensuite incrémenté pour pointer le caractère suivant. Et on reboucle avec le JR BOUCLE.
On fait CTRL + F9, ce qui compile le programme en mémoire (à l’adresse &4000 donc).
On revient ensuite sous BASIC, et on tape :
CALL &4000
Et ô joie, la phrase "AMSTRAD CPC" s’affiche sur notre bel écran bleu, magique non ? Sachant que le programme compilé fait &17 octets, soient 23 octets en décimal, on peut le sauvegarder sur disquette de la manière suivante :
SAVE "texte.bin",b,&4000,23
Vous pourrez ensuite le reprendre en faisant :
10 MEMORY &3FFF
20 LOAD "texte.bin",&4000
30 CALL &4000
RUN
La ligne 10 limite la taille réservée au basic juste en dessous du programme à charger. La ligne 20 charge le programme binaire à l’adresse &4000, puisque c’est à cette adresse qu’il a été compilé. Et la ligne 30 appelle ce programme.
Attention : un programme compilé à une certaine adresse doit ensuite être relogé et exécuté à cette adresse. En effet, l’assembleur s’est basé par rapport à celle-ci pour faire tous ses calculs d’étiquettes. Si vous changez l’adresse, vous risquez donc un super plantage.
Article rédigé par Christophe PETIT
Article créé le : | Jeudi 20 Aout 2015 à 12 h 16 |
Dernière mise à jour le : | Samedi 26 Septembre 2015 à 22 h 01 |