Question simple. La fonction asm
en C est utilisée pour faire l'assemblage en ligne dans votre code. Mais qu'est-ce que ça rend? Est-ce le eax
conventionnel, et si non, qu'est-ce qu'il retourne?Est-ce que __asm {}; retourne la valeur de eax?
Répondre
__asm__
lui-même ne renvoie pas une valeur. C standard ne définit pas comment __asm__
doit gérer la valeur de retour, de sorte que le comportement peut être différent entre les compilateurs. Vous avez indiqué que l'exemple Visual Studio est valide, mais Visual Studio utilise __asm
. __asm__
est utilisé au moins par GCC.
Visual Studio
Pour obtenir le résultat dans un programme C, vous devez placer la valeur de retour à eax
dans le code assembleur, et le retour de la fonction. L'appelant recevra le contenu de eax
comme valeur de retour.
Visual Studio 2015 documentation:
int power2(int num, int power)
{
__asm
{
mov eax, num ; Get first argument
mov ecx, power ; Get second argument
shl eax, cl ; EAX = EAX * (2 to the power of CL)
}
// Return with result in EAX
}
GCC
GCC inline assembly HOWTO ne contient pas un exemple similaire. Cela signifie probablement que vous ne pouvez pas utiliser le retour implicite comme dans Visual Studio. Cependant, le HOWTO montre que vous pouvez stocker le résultat dans la variable C à l'intérieur du bloc d'assemblage et renvoyer la valeur de cette variable après la fin du bloc d'assemblage.
Un exemple d'une fonction de copie de chaîne, la valeur de retour de dest
:
static inline char * strcpy(char * dest,const char *src)
{
int d0, d1, d2;
__asm__ __volatile__( "1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
: "=&S" (d0), "=&D" (d1), "=&a" (d2)
: "0" (src),"1" (dest)
: "memory");
return dest;
}
C'est peu probable; par la spécification C99, sous le comportement de l'implémentation J3:
Le mot-clé asm peut être utilisé pour insérer le langage d'assemblage directement dans la sortie de traducteur (6,8). La mise en œuvre la plus courante est par une déclaration de la forme:
asm (character-string-literal);
Il est donc peu probable qu'un implémenteur va venir avec une approche à la fois insère la langue d'assemblage dans la sortie de traducteur et génère également un code de liaison intermédiaire supplémentaire pour câbler un registre particulier en tant que résultat de retour.
C'est un mot-clé, pas une fonction.
E.g. GCC utilise la sémantique de contrainte de type "=r"
pour vous permettre d'avoir un accès en écriture à une variable dans votre assembly. Mais vous vous assurez que le résultat finit au bon endroit.
Cela dépend du compilateur, mais autant que je sache, il n'est pas une fonction et il ne retourne rien, donc 'int i = __asm__() 'est juste une construction invalide – myaut
Quel compilateur? Quel processeur? La plupart des processeurs n'ont pas de registre eax. – atturri
True. D'accord en supposant que c'est un compilateur de studio visuel (pas sûr de savoir lequel) et un processeur Intel 32 bits. – Delupara