What is the exact meaning of :"=a"(foo) :"a"(foo), "b"(bar));
Il y a une description détaillée de la façon dont les paramètres sont transmis à l'instruction asm here. En bref, cela signifie que bar
va dans le registre ebx, foo
entre dans eax, et après l'exécution de asm, eax contiendra une valeur mise à jour pour foo.
Error: number of operands mismatch for `mul'
Ouais, ce n'est pas la bonne syntaxe pour mul
. Vous devriez peut-être passer du temps avec un manuel de référence de l'assembleur x86 (par exemple, this).
J'ajouterai également que l'utilisation d'inline asm est généralement bad idea.
Modifier: Je ne peux pas répondre à votre commentaire dans votre commentaire.
Je ne sais pas par où commencer. Ces questions semblent indiquer que vous n'avez pas une très bonne compréhension de la façon dont l'assembleur fonctionne. Essayer de vous enseigner la programmation ASM dans une réponse SO n'est pas vraiment pratique.
Mais je peux vous orienter dans la bonne direction.
D'abord, pensez à ce morceau de code asm:
movl $10, %eax
movl $15, %ebx
addl %ebx, %eax
Comprenez-vous ce que cela fait? Que sera dans eax quand cela sera terminé? Que sera dans ebx? Maintenant, comparez cela avec ceci:
int foo = 10, bar = 15;
__asm__ __volatile__("add %%ebx,%%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
);
En utilisant la « une » contrainte, vous demandez gcc pour déplacer la valeur de foo
dans eax. En utilisant la contrainte "b" vous lui demandez de déplacer bar
en ebx. Il le fait, puis exécute les instructions pour l'asm (c.-à-d. add
). A la sortie de l'asm, la nouvelle valeur pour foo
sera dans eax. Trouver? Maintenant, regardons mul
. D'après les documents auxquels je vous ai relié, nous savons que la syntaxe est mul value
. Cela semble étrange, n'est-ce pas? Comment peut-il y avoir seulement un paramètre à mul
?Qu'est-ce que multiple la valeur avec? Mais si vous continuez à lire, vous voyez "Toujours multiplier EAX par une valeur." Ahh. Donc le registre "eax" est toujours implicite ici. Donc, si vous deviez écrire mul %ebx
, ce serait vraiment mul ebx, eax
, mais comme a toujours, il n'y a aucun intérêt à l'écrire.
Cependant, c'est un peu plus compliqué que cela. ebx peut contenir un numéro de valeur 32bit. Puisque nous utilisons ints (au lieu de ints non signés), cela signifie que ebx pourrait avoir un nombre aussi grand que 2 147 483 647. Mais attendez, que se passe-t-il si vous multipliez 2 147 483 647 * 10? Eh bien, puisque 2 147 483 647 est déjà un nombre aussi grand que vous pouvez stocker dans un registre, le résultat est beaucoup trop grand pour tenir dans eax. Donc la multiplication (toujours) utilise 2 registres pour sortir le résultat de mul
. C'est ce que ce lien signifiait quand il se référait "stocke le résultat dans EDX: EAX".
Ainsi, vous pouvez écrire votre multiplication comme ceci:
int foo = 10, bar = 15;
int upper;
__asm__ ("mul %%ebx"
:"=a"(foo), "=d"(upper)
:"a"(foo), "b"(bar)
:"cc"
);
Comme précédemment, ce qui met la barre dans EBX et foo dans eax, exécute alors l'instruction de multiplication.
Et après que l'asm soit terminé, eax contiendra la partie inférieure du résultat et edx contiendra la partie supérieure. Si foo * bar < 2 147 483 647, alors foo contiendra le résultat dont vous avez besoin et upper
sera zéro. Sinon, les choses deviennent plus compliquées.
Mais c'est aussi loin que je suis prêt à aller. Autre que cela, prenez une classe ASM. Lire un livre. PS Vous pouvez également regarder this réponse et les 3 commentaires qui suivent qui montrent pourquoi même votre "ajouter" exemple est "faux". PPS Si cette réponse a résolu votre question, n'oubliez pas de cliquer sur la coche à côté de celle-ci pour obtenir mes points de karma.
Que signifie «a» et «b» ici? – Destructor
Si vous lisez les documents auxquels je suis lié pour asm, vous verrez que les chaînes entre guillemets sont des "contraintes" qui décrivent comment mapper les variables du langage C vers quelque chose que vous pouvez comprendre (voir la section i386 [ici] (https: // gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html)). "a" se réfère au registre eax. "b" se réfère à ebx. –
ok merci. Je l'ai. Mais j'ai toujours un problème. Je veux multiplier les valeurs des variables foo & bar et stocker le résultat dans foo. J'ai visité le lien que vous avez donné à propos de l'insertion multi, mais j'ai encore du mal à savoir ce que je devrais faire exactement pour y parvenir? – Destructor