Obligement - L'Amiga au maximum

Samedi 22 juillet 2017 - 12:38  

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 - Appel de l'assembleur depuis le C et inversement
(Article écrit par Roméo Rapido et extrait d'A-News (Amiga News) - mars 1989)


Appel de l'assembleur depuis le C

Revenons à l'article sur la compilation séparée. Je tiens ici à préciser que les utilisateurs de K-Seka ne peuvent pas lier leur fichier en assembleur avec des fichiers C compilés. De même, les fichiers générés par le Lattice et l'Aztec sont incompatibles. Utilisez donc l'assembleur qui est vendu avec votre compilateur. Seule exception, Assem, l'assembleur du kit développeur qui utilise Blink et est donc compatible Lattice.

Ce qu'il faut absolument savoir sur les appels de fonctions en C et en assembleur : le compilateur passe les arguments par la pile et ceci de droite à gauche. Exemple : si on écrit "Kill(Atari,vite);" le compilateur empilera "vite" puis "Atari" et enfin fera un "jsr _Kill".

Bon et maintenant comment récupérer les arguments en ASM. Il suffit d'utiliser un adressage indirect avec déplacement, en sachant que lors de l'exécution d'un "jsr", le PC est incrémenté de 6 pour pointer sur l'instruction suivante à executer (2=1 mot pour l'instruction et 4 pour l'opérande qui est une adresse) puis est sauvegardé sur la pile (c'est l'adresse de retour utilisée par "rts" qui la dépilera et fera un "jmp" à cette adresse).

Quand on sauvegarde sur la pile, il faut prédécrémenter le pointeur de pile qui pointe toujours sur la dernière valeur empilée. Pour sauvegarder sur la pile, on utilise un adressage indirect prédécrémenté de la forme :

move.l d0,-(sp)

De même, pour dépiler, il faut postincrémenter le pointeur de pile (qui est en fait le registre a7, on peut donc écrire indifféremment a7 ou sp).

move.l (sp)+,d0

Pour avoir accès au premier argument, il suffit d'écrire :

move.l 4(sp),d0

Le déplacement est de 4, ce qui correspond à l'adresse de retour qui a été empilée par le "jsr".

Bon, pour le deuxième, c'est pareil sauf que si le premier argument est un entier court on écrira :

move.l 6(sp),d0

Et si c'est un pointeur ou un entier long :

move.l 8(sp),d0

Déplacement de 4 ou 4+2 suivant la taille du premier paramètre.

Appels du C depuis l'assembleur

Bon, maintenant, voyons le mécanisme inverse : appel du C depuis l'assembleur.

Exemple : appel de la fonction déclarée comme suit :

void triche(arnaque,vol)
short int arnaque;
long vol;

Le code sera de la forme :

move.l d0,-(sp)
move.w d1,-(sp)
jsr _triche

addq.w #6,sp

Que vient faire ce "addq" ? C'est très simple, incrémenter le pointeur de pile est la méthode la plus rapide pour "dépiler" donc on additionne le nombre d'octets que l'on a empilé au SP.

On aurait pu écrire :

move.w (sp)+,d1
move.l (sp)+,d0

Ce qui aurait eu le même effet à part que l'on récupère dans les registres les valeurs passées en paramètre et que l'exécution est plus lente. De plus, il n'y a pas de réel intérêt car les fonctions en C mettent en place une zone de pile dans laquelle elles sauvegardent le contexte, donc pas besoin de dépiler pour récupérer le contexte (quoi que quelques fois ?).

Une dernière remarque : si vous appelez une fonction en ASM qui sauvegarde des registres (ce qui est plus prudent). Exemple : movem.l d0-d3/a1,-(sp)

Il faut modifier vos déplacements pour accéder aux paramètres ; ces déplacements deviennent [4 + nombre_de_reg_sauvegardés x 4], soit ici [4 + 5 x 4] = 24, donc l'accès au premier paramètre se fait via :

move.l 24 (sp),d0

Nota : n'oubliez pas de restituer le contexte par :

move.l (sp)+,d0-d3/a1

Enfin, un dernier mot si vous utilisez l'Aztec C : pas de problèmes, vous avez SDB pour suivre l'exécution en ASM mais si vous utilisez le Lattice C, compilez avec l'option -d (lc1 -d ...) puis liez avec le drapeau ADDSYM au lieu de NODEBUG, cela vous permettra d'utiliser Metascope qui est un débogueur compatible Lattice. Il permet de visualiser la table des symboles, l'exécution en mode trace pas à pas, de modifier les registres, de voir la mémoire en hexa ou désassemblée, modifier la mémoire, placer des points d'arrêt, enfin tout quoi qui faut pour travailler correctement en assembleur.

Pour l'utiliser : ouvrez la table des symboles, cherchez "_main", cliquez sur son adresse et pressez les touches [Amiga+b]. Vous avez installé un "break point", faites [Amiga+g] et l'exécution s'arrêtera au début de votre programme. Metascope permet même de modifier directement le code en mémoire (comme K-Seka mais en cliquant sur une instruction, il demande par quelle autre instruction on veut la remplacer). Il ne lui manque qu'une option Save, dommage.


[Retour en haut] / [Retour aux articles]