Appel fonction en asm

LlufRuS Messages postés 6 Date d'inscription mardi 15 juin 2004 Statut Membre Dernière intervention 26 février 2009 - 23 févr. 2009 à 11:24
LlufRuS Messages postés 6 Date d'inscription mardi 15 juin 2004 Statut Membre Dernière intervention 26 février 2009 - 26 févr. 2009 à 20:42
Bonjour à tous,

je souhaite appeler une fonction provenant d'une librairie dynamique en lui passant directement mes arguments sur la pile (malheureusement, cela ne fonctionne pas).

Si je définie mon pointeur de fonction comme ceci : typedef void (__stdcall * CBGL_TYPE_3D)(GLdouble,GLdouble,GLdouble);
et mon code asm de cette façon :
__asm
        {
            push c
            push b
            push a

            call glVertex3D
        }

ou glVertex3D est récupérer ainsi : glVertex3D=(CBGL_TYPE_3D)GetProcAddress(instanceDLL, "glVertex3d");
je fais n'importe quoi ? (désolé du sens de ma question, mais je ne vois pas comment la tourner autrement.
Il me semblait que la convention stdcall me permet de ne pas avoir à nettoyer la pile or j'obtiens une erreur "The value of ESP was not properly saved across a function call."

Je n'empile pas directement sur esp en faisant un "push variable"?

5 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
23 févr. 2009 à 12:24
GLdouble, c'est 4 ou 8 octets à mettre sur la pile ???

C'est quoi ce petit bout d'asm, toute la fonction ?
Si oui il manque le retour chez l'appelant (RET xxx).

Si c'est un peu d'ASM au milieu d'un code C, alors à bannir absolument, ça empêche toute optimisation du compilo et tu n'as aucune maitrise de ce que tu PUSHes.
Une fonction se fait FULL ASM ou FULL C, mais pas de mixage.

ciao...
BruNews, MVP VC++
0
SebLinck Messages postés 212 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 23 juin 2011
24 févr. 2009 à 14:35
Salut,

Ou alors faut  coder en langage D ...

Cordialement,
Sébastien.
0
LlufRuS Messages postés 6 Date d'inscription mardi 15 juin 2004 Statut Membre Dernière intervention 26 février 2009
26 févr. 2009 à 18:45
Bonsoir à tous,

en premier lieu, désolé du temps de réponse : recherche de logement etc etc qui me prennent pas mal de temps ces derniers temps.

En fait, je cherche à appeller des fonctions provenant d'une librairie ( openGl et extensions... ), au moment de l'appel, je me retrouve avec sur les bras le pointeur de la fonction à appeller, un pointeur vers  le début d'une zone mémoire  contenant  les paramètres  mis les uns à la suite des autres et la taille total de ces paramètres. Reste à savoir comment effectuer l'appel de ma fonction ( je souhaite le faire en assembleur pour une raison d'optimisation de performances )
J'avoue ne pas savoir trop comment faire :  je décremente ebp de la taille des paramètre , recopie comme un sauvage ma zone mémoire dans la pile et effectue un call vers la fonction ? Si je ne m'abuse ce qui suit le @ pour un stdcall va indiquer au compilo la taille de chaque paramètre et donc en gros je ne me soucis plus de rien ? 
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
26 févr. 2009 à 19:55
JE REPETE:
si c'est juste l'appel en ASM alors NIET, c'est une dégradation des perfs et non une optimisation que tu auras.

Si vraiment tu y tiens:
Non, tu ne peux pas présupposer que la fonction utilise EBP comme pointeur temporaire de pile, ce registre peut très bien avoir autre chose de crucial dedans à ce moment.
Tu dois absolument connaitre le mode d'appel de la fonction (stdcall, fastcall ou cdecl) car tu es responsable dans tes instructions ASM du correct replacement du pointeur de pile (ESP ou EBP si stackframe chez l'appelant).
Puisque c'est toi qui PUSH les arguments en ASM, le compilo n'entre pour rien dans l'affaire. Il ne touche pas aux instructions ASM, tu dois donc passer correctement les params de la fonction appelée en te SOUCIANT DE TOUT.

ciao...
BruNews, MVP VC++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
LlufRuS Messages postés 6 Date d'inscription mardi 15 juin 2004 Statut Membre Dernière intervention 26 février 2009
26 févr. 2009 à 20:42
Hum,
en fait je m'exprime mal. Je bosse sur une histoire de "command buffer". En gros les appels aux différentes fonctions OpenGl+extensions sont stockées puis chaque commande est executée par la suite. Je parle d'optimisation de perf car les différents attributs n'ayant jamais la même taille, ils sont stockés en "oubliant" leurs types. Je peux caster le tout en redefinissaant chaques fonctions openGl, c'est cette fonction qui est alors appellée lors de l'execution de mon command buffer, ce qui me permet de connaître la signature exacte de la fonction et donc de caster mes arguments.. etc. Cependant cela me force à faire un appel de fonction en plus. Bref en gros, je préfererais écrire sur la pile et ne plus me soucier des types mais seulement de la taille de chaque attribut et donc appeler mes fonctions qui ont la convention __stadcall. Le stdcall me dit juste que c'est l'appellé qui va nétoyer ma pile et que je dois passer mes attributs de droite à gauche.
Je ne compte pas faire de push ( contrairement à ce que j'avais dit dans mon premier post ) car mes attributs n'auront jamais la même taille.
Mais il doit bien y avoir une façon de faire cela en décrémentant correctement mon pointeur de pile et en placant le tout dans un registre particulier.
Désolé, le problème est clair dans mon esprit mais il est plutôt difficile de restituer le tout par écrit.

Quoi qu'il en soit, merci des différentes réponses et du petit intérêt au problème.
++,
A.
0
Rejoignez-nous