Obligement - L'Amiga au maximum

Jeudi 21 mars 2019 - 00:14  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles en d'autres langues


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


Programmation : C - Transformer un programme C en assembleur
(Article écrit par Denis Jarril et extrait d'Amiga News Tech - juillet 1991)


De nombreux lecteurs nous posent la même question : ne disposant pas de compilateur C, comment profiter des merveilleux programmes C de Frédéric Mazué, Stéphane Schreiber et autre Pascal Amiable ?

Quelqu'un d'un tant soit peu mercantile aurait certainement répondu : abonnez-vous à une formule avec disquette... Mais l'ANT, comme à son habitude, va beaucoup plus loin que ça et vous propose carrément de vous prendre par la main, en décortiquant pour vous une (la ?) manière de s'y prendre. Et comme un exemple concret est toujours plus parlant que de longs discours, j'ai choisi d'illustrer mon propos avec un très vieux programme paru dans l'ANT numéro... 6 (Commodore Revue numéro 17) : le "sectorisateur" de la société Loriciel.

Sectorisateur ?

Un rapide rappel sur le but et l'utilité de ce programme : présenté dans l'ancienne rubrique ViewPort, dans laquelle des éditeurs livraient leurs astuces de programmation, et programmé par Jean-Pierre Vitulli, Sectorise permettait d'écrire sur une suite de secteurs de la disquette placée en DF0:, par le biais du trackdisk.device, un fichier AmigaDOS quelconque (image, musique, programme exécutable...).

Préparatifs

De quoi a-t-on besoin pour "transformer" un programme C en son équivalent assembleur ? Tout simplement d'un bon assembleur. J'entends par là "macro-assembleur", c'est-à-dire capable de jongler avec des fichiers includes et, éventuellement, de produire un code reliable plutôt qu'exécutable. Comme vous devriez maintenant en avoir l'habitude, c'est le Devpac II qui a été choisi, mais l'assembleur du Lattice, le DP a68k ou même l'ancêtre MetaComCo feront l'affaire. Un peu de documentation ne fera pas de mal non plus et pour une fois, la Bible De L'Amiga (deuxième édition, celle à la couverture bleue) conviendra parfaitement. Mes précédents articles dans l'ANT (utiliser amiga.lib, mélange C/assembleur) ne seront non plus pas de trop. Quelques connaissances, même rudimentaires, du langage C seront également les bienvenues.

Problèmes

A quel type de problème se heurte-t-on dans ce cas-là ? Le plus gros concerne les structures du C, intensivements utilisées sur l'Amiga. En effet, alors que le compilateur C sait d'office la taille des champs des structures, l'assembleur ne la connaît absolument pas, et qui plus est, ne se plaindra pas le moins du monde si vous référencez un mot long alors que le champ est de la taille d'un octet. D'où l'utilité de la documentation dont il est question dans le paragraphe précédent.

Un autre problème concerne les paramètres des programmes ; alors que la startup des programmes écrits en C contient une routine qui décompose la ligne de commande du CLI pour remplir le tableau argv et donner sa valeur correcte à argc, rien de tel n'existe en assembleur. De même, le C dispose d'une bibliothèque de fonctions de base (printf, str..., fprintf, etc.) dont l'assembleur ne dispose pas. Une première solution consiste donc à réécrire de telles routines en assembleur : on obtient ainsi un code plus compact, répondant parfaitement à nos besoins, mais au prix d'un travail supplémentaire fastidieux. Une seconde solution, par ailleurs celle que j'ai retenue ici, consiste à relier la startup et la bibliothèque C avec le programme assembleur principal. Enfin, une troisième possibilité, celle que j'utilise le plus souvent par fainéantise consiste à se débrouiller comme on peut pour les obtenir à un moment ou à un autre.

Enfin, dernière difficulté, le choix des variables locales et des variables globales. Là, tout dépend de l'importance de ces variables. Par exemple, un pointeur sur une zone de mémoire allouée devra être conservé, histoire de rendre cette mémoire au système en fin de programme. Par contre, si cette allocation a lieu dans un sous-programme et que la libération correspondante survient à la fin de ce même sous-programme, on aura tout avantage à conserver ce pointer dans un registre An, voire sur la pile dans le pire des cas. Dans le même ordre d'idées, un compteur de boucle for() sera avantageusement placé dans un registre Dn, même s'il a été déclaré global dans le programme C.

Pointeurs et tableaux

Le C est un langage orienté "pointeurs". Cela signifie qu'il offre tout un tas de facilités pour leur gestion (déclaration, changement de type (casting), arithmétique, etc.). En assembleur, un pointeur est une adresse 32 bits, un point c'est tout. Considérez l'exemple suivant, par ailleurs totalement inutile :

C

Transcrire une telle fonction en assembleur ne posera pas de problème particulier, pour peu que l'on se rappelle que toto pointe un tableau de mots de 16 bits, et qu'en tant que tel, le compilateur C l'incrémente de deux octets lorsqu'il rencontre l'instruction toto++, et de six octets lorsqu'il rencontre toto + 3. Le code assembleur de cette même fonction ressemblera donc à quelque chose du genre :

C

Si la comparaison post-incrémentée se charge pour nous de maintenir a1 aligné sur des mots, l'addition finale devra prendre ce fait en compte.

Complexité

Comme tout langage évolué qui se respecte, le C permet d'écrire en une seule ligne de programme plusieurs opérations, que le compilateur se chargera de décortiquer en une suite d'instructions assembleur cohérente, suivant la priorité des différents opérateurs utilisés, l'utilisation ou non de parenthèses, etc. Par exemple, la ligne suivante, que l'on rencontre très souvent dans des programmes en C sur l'Amiga :

C

L'ordre des opérations est le suivant :
  • Initialiser a1 et d0 pour l'appel à OpenLibrary.
  • Appeler OpenLibrary.
  • Sauver le résultat dans la variable GfxBase.
  • Si ce résultat est nul, aller à CleanExit.
  • Sinon, continuer le programme.
Ça, c'était un cas facile. Considérez maintenant l'instruction :

C

Déjà moins évident, non ? La suite des opérations est la suivante :
  • Prendre le pointeur fl_Volume dans la structure MyLock.
  • Le convertir du BCPL au C.
  • Y puiser le pointeur dl_Name.
  • Le convertir du BCPL au C.
Et encore, ce ne sont pas là les cas les plus ardus. Il faudra apporter une attention toute particulière aux boucles du genre for() et while( ), dont la condition d'arrêt peut souvent inclure un ou plusieurs appels à un ou des sous-programmes.

Trêve de bavardages

Pour faciliter un peu les choses, j'ai inclus en commentaire du source assembleur, les lignes de source C telles qu'elles apparaissaient dans le listing original. A vous d'en faire bon usage.

C
C
C
C
C


[Retour en haut] / [Retour aux articles]