Question

Donc, je voudrais être en mesure d'appeler des fonctions d'une dll c++.Pour certaines raisons, je voudrais lancer un appel à partir d'un __asm bloc dans mon code C++.Ma question est la suivante:Je sais qu'avant que j'appelle la fonction, je dois pousser ses arguments sur la pile dans l'ordre spécifié par la fonction de la convention d'appel.Cependant, puis-je simplement faire quelque chose comme ceci:

int a=5;   
double b = 5.0;  
__asm{  
       push b 
       push a  
       call functionAddress  
}

Ce qui m'inquiète est le fait que je semble me rappeler que le mot standard de la taille de l'assemblée est 2bytes, alors que la taille d'un int en C++ est généralement de 4 octets, et 8 octets pour un double.Ainsi , dans l'exemple ci-dessus, suis-je vraiment sur la pleine valeur de chaque variable, ou tout simplement les deux premiers octets?Si le code ci-dessus n'est pas correct, ce qui serait le bon moyen de le faire?Aussi, si la fonction que nous appelons renvoie un double, où est cette valeur est stockée?Je suis en supposant qu'elle ne peut pas être dans un registre, parce qu'il ne peut stocker que de 32 bits ( 4 octets ).Toute aide à ce désordre serait grandement apprécié :)

Était-ce utile?

La solution

Pour pousser les 8 octets de valeurs telles que des doubles, vous ne serez pas en mesure d'utiliser régulièrement PUSH de l'instruction.Et vous n'avez pousser à virgule flottante paramètres (ou double) sur le floating-point de la pile.Vous avez besoin de mettre ces graisses paramètres sur la pile "à la main".Par exemple, de pousser π comme paramètre d'une fonction f:

  __asm {
    FLDPI                    // load pi onto FP stack
    SUB ESP,8                // make room for double on processor stack
    FSTP QWORD PTR [ESP]     // store pi in proc stack slot (and pop from FP stack)
    CALL f
    ADD ESP,8                // clean up stack (assuming f is _cdecl)
  }

Autres conseils

Le 32-bit x86 l'architecture automatiquement plaquettes de valeurs poussé sur la pile à 32 bits.

Il y a quelque chose que vous devez garder à l'esprit.Si la fonction que vous appelez utilise le __cdecl convention d'appel, vous devez "pop" ce qui vous a poussé par la suite.Cependant, pour __stdcall fonctions que vous ne devez pas faire cela.

extern "C" int    __cdecl   function1(int, double);
extern "C" double __stdcall function2(char, char*);

int a = 5;
double b = 5.0;
int retval1;
char c = '5';
char *d = "Hello";
double retval2;

__asm {
    push b
    push a
    call function1
    add esp, 4*2 // "pop" what we pushed
    mov retval1, eax
    push d
    push c
    call function2
    mov retval2, eax
}

Généralement, vous seriez en la poussant à la taille complète de l'ordinateur mot.Cela varie en fonction de la puce, mais sur un 32 bits, Intel serait de 4 octets, et sur une version 64 bits d'Intel, serait 8 (selon le compilateur -- Visual Studio encore prend uniquement en charge les IA32 assemblée -- donc 4 octets).

La meilleure réponse est à chercher dans la documentation de votre compilateur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top