Utilisation de librairies C/C++ dans un projet en langage assembleur
Tutoriel réalisé par Faiseur
Niveau: [ Intermédiaire ]
Dans cet tutoriel nous allons nous servir de la librairie « msvcrt » pour illustrer la polyvalence possible, en assembleur, avec des fonctions C/C++. Cette librairie est fournie dans les kits de développement C/C++.
Tout d'abord telechargez l'exemple ici
Une partie des fonctions de « msvcrt » sont redondantes avec les librairies fournies par les assembleurs courants, mais pas toutes. De plus, certaines fonctions s’avèrent pratiques.
Pour intégrer les fonctions de cette librairie avec un assembleur, dans notre exemple Masm, il est nécessaire de créer des définitions de prototypes pour chaque fonction appelée dans cette librairie. Dit autrement: Masm ne sait pas quoi faire lorsque nous utilisons telle ou telle fonction de cette librairie, il est nécessaire de lui expliquer comment il doit procéder pour appeler ces fonctions afin de les inclure dans notre programme compilé.
Avec Masm32 les définitions correspondent aux fichiers « .inc ». Le fichier "*.inc" est nécessaire pour la fonction "invoke", mais on peut s'en passer, par contre il permet et c'est cela qui est important, d'inclure correctement la bibliothèque lors de l'édition des liens (LINK).
L'adaptation de cette librairie pour Masm a déjà été faite par des utilisateurs, ce qui rend disponible la quasi-totalité des fonctions de cette librairie. Dans l’exemple joint à ce tutoriel vous trouverez les fichiers « msvcrt.lib » et « msvcrt.inc », qui vous permettrons de vous servir de cette librairie dans vos programmes Masm.
A noter que si vous souhaitez utiliser les macros de Masm32 (le fichier « macros.asm ») vous aurez des erreurs lors de la compilation, simplement parce que certains noms utilisés par les macros sont identiques aux fonctions de cette librairie. Pas de panique, les macros en conflit ne sont pas essentielles et de plus elles ont une fonction identique à cette librairie. Si vous souhaitez vous servir des macros de Masm32 vous pouvez donc, au choix:
- Effacer individuellement les macros en conflit de la liste du fichier « macros.asm »
- Renommer les macros du fichier « macros.asm » qui posent problème afin de résoudre le conflit
Le résultat de ce travail préalable est le suivant: nous pouvons appeler les fonctions de cette librairie avec « invoke », sans plus de formalités !
Passons sans plus tarder au code source de notre exemple, qui est fournit dans la même archive.
Notez que chaque fonction de msvcrt étudiée dans ce tutoriel pointe sur son lien direct MSDN. N'hésitez pas à vous documenter plus avant sur cette précieuse source d'information !
Fichier .asm
- Code:
include MscvrtExemplebyF.inc
comment *
Exemple d'utilisation d'une librairie C/C++ avec Masm: asm+c dans un même projet
par Faiseur
*
.data
Listing db "Exemple simple d'utilisation de la librairie msvcrt.lib - librairie C/C++",13,10,13,10,\
" Fonctions C/C++ utilisées:",13,10,13,10,\
" < _strtime >",13,10,\
" < time >",13,10,\
" < srand >",13,10,\
" < _ltoa >",13,10,\
" < sprintf >",13,10,\
" < exit >",13,10,13,10,\
" - Heure locale: %s",13,10,13,10,\
" - Nombre aléatoire depuis l'heure locale: %s",13,10,13,10,\
" - Division par 100 de la valeur: %s",0
Message db "Résultat des fonctions msvcrt.lib - C/C++ library",0
.code
start:
invoke _strtime,addr szTime
invoke time,NULL
invoke srand,eax
invoke rand
push eax
invoke _ltoa,eax,addr szRandom,10
pop eax
invoke ldiv,eax,100 ; divisionde la valeur du random par 100
invoke _ltoa,eax,addr szRandomDiv,10
invoke sprintf,addr Result,addr Listing,addr szTime,addr szRandom,addr szRandomDiv
invoke MessageBox,0,addr Result,addr Message,0 ; on affiche le tout
invoke exit
end start
La taille de l’exécutable généré par notre exemple reste ridicule, environ 2ko pour utiliser les 4 fonctions de la librairie.
Analyse du code
- Code:
invoke _strtime,addr szTime
Exemple d'utilisation de la fonction _strtime, qui permet de récupérer la date de l'heure locale. Le résultat est placé dans szTime directement comme chaîne de caractère en format heure/minute/sec.
- Code:
invoke time,NULL
time récupère l’heure locale mais nous allons nous servir de sa valeur de retour.
MSDN nous dit:
Return the time as seconds elapsed since midnight, January 1, 1970. There is no error return.
Autrement dit, cette valeur ne sera jamais une seule fois identique ! C'est un bon choix pour générer un nombre aléatoire. Nous allons nous servir de ce résultat toujours changeant avec srand.
- Code:
invoke srand,eax
srand permet de fixer un résultat aléatoire sur la fonction rand. Si nous ne faisions pas cela la valeur serait toujours identique avec le random. Comme la valeur placée avec srand est toujours différente (grâce à la valeur de retour de "time") nous sommes sûrs de générer un nombre toujours aléatoire.
- Code:
invoke rand
rand génère le nombre aléatoire.
- Code:
push eax
invoke _ltoa,eax,addr szRandom,10
_ltoa permet de convertir un entier en chaîne de caractère. Il est possible de choisir la base de conversion, ici base 10. Nous convertissons donc le résultat pour être affiché plus tard (note: il serait possible d'éviter d'utiliser cette fonction mais nous souhaitons démontrer ici certaines fonctions de la librairie msvcrt).
- Code:
pop eax
invoke ldiv,eax,100
ldiv permet de diviser une valeur (numérateur) par son dénominateur. Ici nous divisons par 100.
La suite se passe de commentaire particulier. Nous convertissons la valeur divisée par 100 en chaîne de caractère puis nous affichons toutes les chaînes en les envoyant comme paramètres de la fonction sprintf, qui s'utilise de manière similaire à l'API wsprintf:
- Code:
invoke _ltoa,eax,addr szRandomDiv,10
invoke sprintf,addr Result,addr Listing,addr szTime,addr szRandom,addr szRandomDiv
Nous affichons le résultat avec une MessageBox et nous quittons le programme avec une autre fonction de msvcrt.lib: exit.
- Code:
invoke MessageBox,0,addr Result,addr Message,0 ; on affiche le tout
invoke exit
Simple non ?

0 commentaires:
Enregistrer un commentaire