Obligement - L'Amiga au maximum

Dimanche 19 novembre 2017 - 05:54  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Hit Parade
 · 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 in other languages


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Moteurs de recherche
 · Pages de liens
 · Constructeurs matériels
 · Matériel
 · Autres sites de matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Développeurs logiciels
 · Logiciels
 · Développeurs de jeux
 · Jeux
 · Autres sites de jeux
 · Scène démo
 · Divers
 · Informatique générale


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 - réduire la taille des programmes utilisant printf
(Article écrit par Squonk et extrait d'Amiga News - avril 1991)


print f + puts = 124 octets !

Quelle est la signification de cette équation bizarre ? Bon, je suppose que tous ceux d'entre vous qui ont tapé un jour un programme en C ont dû au moins recopier le fameux "Hello, World!" du Kernighan & Ritchie.

Ce qui vous a certainement un peu inquiété, c'est la taille de l'exécutable obtenu par rapport à la taille du source (eh bien, si le C est comme ça...) ! Ces rondeurs proviennent en fait de l'utilisation de "printf". Voici donc un moyen de passer la taille du "Hello World!" de 5 ko à 2 ko...

Les vieux routards de la galaxie Amiga se rappellent probablement d'un article de Cédric Beust qui détaillait un moyen de remplacer le "printf" de votre compilateur par un morceau de code appelant une routine de la ROM (RawDoFmt). L'intérêt ? Puisque la routine de décodage des arguments est en ROM, elle n'est pas dans votre programme ! Je pousse la solution un peu plus loin en proposant de remplacer purement et simplement le "printf" original par un bout de code à moi, sans toucher à vos sources. Il suffit de relier vos programmes en C avec ma routine et vous gagnez 3 ko de code dans l'exécutable !

RawDoFmt

Tout d'abord, on peut se demander d'où provient l'aspect un peu magique de la routine "RawDoFmt" ? Eh bien , M. Commodore ne nous dit pas toujours tout, puisque cette routine qui est présente depuis le début de l'Amiga dans les ROM n'est officielle que depuis le 2.0. Elle est utilisée notamment par le "ROM-Wack", le débogueur en ROM et... par le gourou lui-même ! Devant ce mutisme, il n'y a pas de doute, une seule solution : à l'assaut (c'est la dernière mode américaine) ! En disséquant la bête, j'ai pu éclaircir le fonctionnement de cette routine. Voici ses paramètres d'appel :

RawDoFmt(Format, Args, putchar, Buffer)
A0 A1 A2 A3

Format : chaîne de formatage type "printf". Il y a quelques restrictions, détaillées dans le source que je vous soumets :
  • Pas de flottants.
  • Pas de conversion octale.
  • Entier 16 bits par défaut, quelles que soient les options de votre compilateur, 32 bits si "l" est précisé.
Args : pointeur sur un tampon mémoire contenant les arguments pour la conversion, suivant la chaîne de format.

putchar : pointeur sur la fonction utilisateur de sortie de caractères.

Buffer : tampon mémoire à l'usage exclusif de la routine putchar précédente.

Ceci répond donc aux interrogations de Cédric concernant les restrictions de cette routine. mais aussi me donne quelques idées sur le sujet... Le gros problème d'une routine printf, c'est qu'elle ne connaît pas la longueur finale de la chaîne à imprimer. Bien sûr. elle peut limiter arbitrairement la longueur des chaînes, m'enfin... La solution m'est apparue à l'énoncé du dernier argument. En effet, je croyais que le tampon mémoire passé à RawDoFmt() était utilisé en interne pour des conversions du type int -> chaîne. Eh bien il s'avère que pour ce type de conversion, RawDoFmt() s'alloue un tampon dynamique tout seul et ne touche absolument pas au paramètre qui lui est passé dans A3, qui n'est que transmis à la routine putchar() de l'utilisateur pour chaque caractère à imprimer.

Tampon mémoire

Partant de là, on peut considérer que le format de ce tampon est libre ! L'astuce consiste donc à allouer dynamiquement un tampon de longueur fixée dans notre "printf' (le code est ainsi réentrant, c'est-à-dire utilisable par plusieurs utilisateurs en même temps) par un "link" et de réserver le premier mot de ce tampon comme compteur de caractères. Puisque j'écris également la routine putchar() qui va recevoir ce tampon, cela va me permettre de tester le dépassement de tampon mémoire et d'imprimer morceau par morceau si la chaîne est trop longue. Je peux donc traiter virtuellement des chaînes de la longueur de la mémoire physique !

Le rôle de notre routine printf() est donc d'allouer un tampon mémoire dynamique, de préparer les arguments pour RawDoFmt(), de désallouer le tampon mémoire et de retourner la bonne valeur à l'utilisateur.

La routine putchar() reçoit le fameux tampon mémoire, se contente d'y stocker le caractère qui, lui, est passé par RawDoFmt() et d'appeler le cas échéant puts() si la chaîne est finie ou si le tampon est plein.

Tant que j'y étais, j'ai retouché la routine puts() de Cédric pour intégrer un strlen() rapide. Sa routine était déjà très bien, puisque contrairement au printf de mon compilateur, elle peut facilement imprimer dans n'importe quelle fenêtre et non pas seulement dans la fenêtre de lancement.

Bien que non testé avec les ROM 2.0, mon programme devrait marcher correctement, puisque M. Commodore gère maintenant la routine RawDoFmt()...

Voici le résultat des courses avec Aztec 3.6 :

C

J'espère que ce bout de code vous servira autant qu'à moi. Non seulement il permet de gagner 3 ko sur les programmes utilisant printf(), mais il montre le fonctionnement en assembleur de link/unlk pour allouer des tampons mémoire dynamiques (je hais les DS.X de l'assembleur !).

C
C
C


[Retour en haut] / [Retour aux articles]