Interfacer du code assembleur et du C

Dernière mise à jour le 5 décembre 2007 à 14:51 par kilian
Publié par kilian

Interfacer du code assembleur et du C



Introduction


Si, à tout hasard, vous souhaitez utiliser du code assembleur dans votre code C, ou encore utiliser une fonction d'une librairie externe depuis l'assembleur, eh bien c'est tout à fait possible et il y a des solutions plus confortables que d'autres pour faire ça.
Je préviens tout de suite que ce sujet n'est pas un cours d'assembleur!
De même je fais référence à des notions de convention de passage de paramètres sous x86, enfin... juste cdecl et stdcall.

Appeler du code assembleur écrit dans un fichier source externe

Avec Nasm (x86 uniquement)


Imaginons que vous ayez un fichier source comme celui-ci appelé test.c:
void additionne(int nb);

int main()
{
	int i;
	for(i=0; i<10; i++)
	{
		additionne (i);
	}
	return 0;
}


Votre fonction additionne n'est pas définie et vous voudriez qu'elle le soit en assembleur.
On va donc l'écrire dans un fichier externe pour pouvoir la compiler avec nasm.
Cette fonction additionne va en fait faire une addition cumulée et l'afficher au fur et à mesure.
C'est à dire que
additionne(2) donnera 2
puis encore additionne(2) donnera 4 etc...
Je fais ça pour pouvoir vous montrer comment déclarer une vaiable globale avec nasm et comment appeler une fonction externe comme printf depuis l'assembleur.

On crée un fichier appelé add.asm.
Du début à la fin on aura

_La référence aux fonctions externes:
;Permet de faire appel à printf
extern printf


_ La section de données:
section .data
        ;La chaîne passée à printf pour afficher notre addition cumulée (0xa = saut de ligne)
	msg db 'Addition cumulee: %d',0xa, 0 
        ;La variable qui mémorisera l'addition cumulée. Elle est égale à 0 au début
	addition_cumulee dw 0 


_ Le code:

section .text
        ;On rend visible notre fonction additionne pour les fichiers externes
	global additionne 

;Fonction en convention cdecl
additionne:
	push ebp
	mov  ebp, esp
	push ecx

	mov ecx, [addition_cumulee]
	add ecx, [ebp + 8]     ; On fait notre addition:  nb + addition_cumulée
	mov [addition_cumulee], ecx    ; On met à jour addition_cumulée = addition_cumulée + nb
	push ecx
	push msg
	call printf     ; Equivalent de printf(msg, ecx). C'est un appel de type cdecl.
	add esp, 8

	pop ecx
	leave
	ret


A présent on va compiler le tout.

Compilation/Execution sous Linux


On compile notre fichier asm:
nasm -f elf add.asm

On compile test.c et on le met en lien avec notre fichier assembleur compilé:
gcc test.c add.o -o test


Et on teste:
./test
Addition cumulee: 0
Addition cumulee: 1
Addition cumulee: 3
Addition cumulee: 6
Addition cumulee: 10
Addition cumulee: 15
Addition cumulee: 21
Addition cumulee: 28
Addition cumulee: 36
Addition cumulee: 45

Avec Gcc (multiplateforme)


(à faire)
Meilleures réponses pour « Interfacer du code assembleur et du C » dans :
La compilation et les modules en C et en C++ VoirCet article a pour vocation d'introduire les notions de bases de la compilation en C et en C++ et de la programmation modulaire. Il permet de mieux comprendre les messages d'erreur du compilateur. Les notions abordées ici sont indépendantes du...
Télécharger Code::Blocks Studio VoirCode::Blocks est un IDE multi-plateforme (Linux, Mac et Windows) entièrement codé en C++. Code::Blocks est basé sur un système de plugins, ce qui permet de le faire évoluer très facilement sans devoir le recompiler. La compilation, qui peut se...
Introduction à l'assembleur VoirLes prérequis nécessaires Le langage assembleur est très proche du langage machine (c'est-à-dire le langage qu'utilise l'ordinateur : des informations en binaire, soit des 0 et des 1). Il dépend donc fortement du type de processeur. Ainsi il...