GCC inline assemblage d'erreur: Erreur: junk `(%esp) " après l'expression
GCC inline assemblage d'erreur: Erreur: junk `(%esp) " après l'expression
Je suis étudiant en gcc assembly en ligne. Mon environnement est Win 7 32 bits, mingw-gcc 4.6.1.
J'ai eu un problème sur le 'm' de contrainte. Voici ma fonction c code:
static int asm_test(int a, int b)
{
int c = 0;
__asm__ __volatile__(".intel_syntax\n"
"mov eax, %1\n" //error
"mov edx, %2\n" //error
"add eax, edx\n"
"mov %0, eax\n" //error
".att_syntax"
:"=m"(c)\
:"m"(a),"m"(b)\
:"eax","edx"
);
return c;
}
Pour at&t code, il est comme ceci:
static int asm_test(int a, int b)
{
int c = 0;
__asm__ __volatile__(
"movl %1, $eax\n" //error
"movl %2, $edx\n" //error
"addl $edx, $eax\n"
"movl $eax, %0\n" //error
:"=m"(c)\
:"m"(a),"m"(b)\
:"eax","edx"
);
return c;
}
Pour chacune des trois lignes qui fonctionnent d'entrée/sortie opérandes, gcc de générer une erreur lors de la compilation, lire comme ceci:
C:\Users\farta\AppData\Local\Temp\cc99HxYj.s:22: Erreur: junk `(%esp) " après l'expression
Si j'utilise " r " pour l'entrée/la sortie contrainte, le code du travail. Mais je ne comprends pas pourquoi cela fonctionne et ce que l'erreur est synonyme de. Quelqu'un peut-il me dire? Autant que je sache, " m " est plus qu'à dire à gcc de ne pas allouer les registres, mais directement accès dans la mémoire si l'asm inline code essayez d'accès d'entrée/sortie des opérandes. Est-ce correct?
Merci beaucoup.
- Je ne suis pas sûr que vous pouvez utiliser Intel syntaxe là. Essayez avec AT&T.
- Merci. J'ai essayé équivalent at&t asm code. Le message d'erreur sont tous les mêmes. Je pense qu'il n'est pas causé par Intel de la syntaxe.
- Bien montrer le AT&T de la syntaxe. La plupart des gens qui ne GCC inline assembler sera plus familier avec ce que l'Intel.
- AT&T syntaxe est: asm __volatile__( "movl %1, $eax" "movl %2, $edx" "addl $edx, $eax" "movl $eax, %0" :"=m"(c)\ :"m"(a),"m"(b)\ :"eax","edx" )
- Merci d'éditer votre question à ajouter le code, il est très difficile de lire dans les commentaires. En général, vous devez éditer votre question lorsque des précisions sont demandées dans les commentaires, afin que tout le monde voit, les informations supplémentaires directement. (Il y a un lien "modifier" à droite sous les balises que vous pouvez utiliser.)
- ce n'est pas AT&T i386 syntaxe,
$
est pour les constantes, l'utilisation%%
en face de vous inscrire des noms, comme%%eax
. - Merci beaucoup. Le at&t code a été ajouté.
- Il semble que j'ai besoin d'en lire plus sur la syntaxe at&t asm code. Merci beaucoup.
Vous devez vous connecter pour publier un commentaire.
Le problème ici, c'est la GCC génère AT&T de la syntaxe de la construction pour la
%0
,%1
et%2
. Si vous regardez l'assembly généré, il ressemble:qui n'est pas valide Intel syntaxe.
En général, vous n'avez pas besoin de l'inclure dans la ligne d'assemblage explicite/charge de l'exploitation du magasin - il suffit de spécifier registre de la contrainte, et le compilateur va générer des charges/magasins par lui-même. Ceci a l'avantage que, même si vos variables (paramètres locaux) ne résident pas dans la mémoire à tout, mais sont dans les registres de votre code reste correct comme dans le cas si vous l'avez explicitement mis de la mémoire de chargement/magasins.
Pour votre exemple, essayez le code suivant, l'assemblée (
gcc -S
) et remarquez comment le compilateur va effectuer des mouvements de l'argument de la zone (par exemple, la pile sur x86) tout par lui-même.}
imul
), oui, mais, en général, laisser de GCC pour allouer des registres par lui-même.gcc
d'intel à l'aide de-masm=intel
.