La programmation en assembleur est casse-pieds, sauf pour des parties sensibles de programmes. Vous devrier utiliser les outils appropriés en fonction des outils que vous souhaitez créer. Donc ne choisissez pas l'assembleur lorsque cela ne correspond pas. C, OCAML, perl, Scheme, peuvent être un meilleur choix pour vos programmes.
Toutefois, il existe certains cas où ces outils ne donnent pas un contrôle assez fin sur votre machine, et l'assembleur est alors utile, voir nécessaire. Dans ces cas, vous allez apprécier un système de macro-programmation et de méta-programmation qui vous permet de ne définir qu'une seul fois des symboles que vous répettez et ainsi pouvoir les utiliser bon nombre de fois grâce à un système d'expansion. Cela permet une programmation plus sûre, de modifier le code plus simplement, etc. Un pur assembleur n'est généralement pas suffisant, même lorsque vous ne faîtes que de petites routines que vous utilisez dans des programmes C.
gcc
permet (et demande) à ce que vous spécifiez des contraintes
sur les registres dans votre code en ligne, de telle manière que
l'optimiseur le sache. Donc, l'assembleur en ligne est vraiment fait de
modèles, et pas forcément de code au sens du terme.
Ensuite, vous pouvez transformer votre code en macros CPP, de telle
manière que n'importe qui puisse s'en servir comme fonction en ligne ou
macro C. Les fonctions en lignes ressembles de très près aux macros,
mais elles sont parfois plus propres à utiliser. Faites attention car
dans un tel cas, le code sera dupliqué, donc seules des étiquettes
locales (comme 1:
) devraient être définies
dans le code assembleur. Toutefois, une macro-commande pourrait
autoriser le passage d'une étiquette non définie en local en paramètre.
Notez également que certaines erreurs de votre code ou de gcc
peuvent apparaître lorsque vous utilisez des fonctions en ligne en
assembleur si les contraintes de registres n'ont pas été déclarées
proprement.
Enfin, le langage C peut être considéré comme étant une bonne abstraction au langage assembleur, ce qui vous évite une bonne partie des problèmes de l'assembleur.
Prenez garde à certaines optimisations qui peuvent passer des arguments
à des fonctions via des registres. Dans ce cas, ces fonctions pourraient
ne plus être joignables de l'assembleur d'une manière standard,
à moins que vous n'utilisiez le mot clef asmlinkage
.
Consultez les sources du noyau Linux pour plus d'exemples.
gas
ne possède absolument aucune capacité de gestion de macros.
Toutefois, gcc
fait passer les fichiers .S
via
cpp
avant d'être donné à gas
. Les fichiers
.s
ne sont générés qu'une seule fois et passés directement à
gas
. Encore une fois, consultez les sources de Linux.
Ce programme correspond au préprocesseur de macro commandes
en assembleur de GAS. Consultez sa documentation en texinfo
.
Il gère quelques macros assez simple, mais je n'ai pas réussi à trouver de la documentation. Maintenant, les sources sont très parlants, donc si vous êtes intéressé, vous devriez les comprendre très facilement. Si vous avez besoin de plus que le stricte minimum, vous devriez utiliser un filtre externe (voir un peu plus bas...)
CODE
et END-CODE
sont des macros-commandes
qui ne varient pas en fonction du mode, donc vous avez acccès à
toute la puissance des mots clefs du langage FORTH dans le code assembleur ;
Quelque soit la gestion de macro supportée par votre assembleur, ou quelque soit le langage que vous utilisez (même C !), si le langage n'est pas assez puissant pour vous, vous pouvez passer les fichiers à travers un filtre externe en incluant une règle dans le Makefile, comme par exemple :
%.s: %.S autre_dependances $(FILTRE) $(OPTIONS_FILTRE) < $< > $@
cpp
n'est pas vraiment très expressif mais il est assez
bon pour des opérations simples. Il est standard et appelé d'une
manière transparente par gcc
.
Comme exemple de limitation, vous ne pouvez pas déclarer d'objets de telle manière que les destructeurs soient automatiquement appelés à la fin du bloc de déclaration. Vous ne pouvez pas déclarer les données et le code qui va les manipuler, etc.
cpp
est livré avec le compilateur C. gcc
(voir
ci-dessus) est un compilateur C libre, qui le contient.
m4
vous donne toute la puissante du traitement de macro instructions,
avec un langage équivalent à celui de Turing,
la récursivité, les expressions régulières, etc. Vous pouvez faire tout
ce que vous ne pouviez pas faire avec cpp
.
Récupérez macro4th/This4th à partir de
ftp://ftp.forth.org/pub/Forth/ dans Reviewed/ ANS/ (?)
.
Des exemples de programmation avancée sont disponibles dans
les sources de Tunes 0.0.0.25
.
Toutefois, il y a pas mal de problèmes de sémantiques avec les
quotes qui vous obligent à utiliser des continuation explicites,
des macros récursives si vous souhaitez faire de la programmation
avancée (ce qui n'est pas sans rappeler -- d'ailleurs, est-ce que
quelqu'un a déjà essayé d'utiliser TeX comme un macroprocesseur pour
autre chose que du traitement de texte ?).
Ce n'est pas pire que cpp
car il n'autorise pas les quotes et
la récursivité.
La bonne version de m4
a récupérer est
la version GNU m4 1.4
(ou plus récente si elle existe),
qui possède le plus de caractéristiques et le moins de bugs et
de limitations.
Vous pouvez écrire vos propres filtres d'expansion de macros
avec les outils habituels : perl
, awk
, sed
, etc.
C'est rapide à faire, et vous contrôlez tout. Mais bien sûr,
toute la puissante des traitement dépend de vous.
Au lieu d'utiliser un filtre externe qui expanse les macro-commandes, une manière de travailler consiste a écrire des programmes qui écrivent des parties ou tous les autres programmes.
Par exemple, vous pourriez utiliser un programme qui génère le code source pour générer les tables correspondantes aux opérations sinus et cosinus, pour extraire une représentation code source d'un binaire, pour compiler vos images en routines d'affichage rapide, pour extraire de la documentation, du code d'initialisation et de terminaison, des tables de descriptions. Cela pourrait être un code source généré à partir de scripts perl, shell, scheme qui effectue le traitement (particulièrement utile lorsque certains types de données doivent être dupliqués dans bon nombre de tables de références croisées et dans du code).
Pensez-y !
Chapitre suivant, Chapitre Précédent
Table des matières de ce chapitre, Table des matières générale
Début du document, Début de ce chapitre