2017-09-24 2 views
0

C'est la première fois que j'écris du code assembleur. Au premier début, j'ai écrit

#include<stdio.h> 
int main(){ 
    int x,y; 
    asm("movl $2,%eax"); 
    asm volatile(
        "movl $1,%0\n\t" 
        "movl %0,%%ebx\n\t" 
        "leal 2(%%ebx,%%eax,$2),%1" 
        :"=m"(x),"=r"(y) 
        ); 
    printf("x is %d, y is %d\n",x,y); 
    return 0; 
} 

Le compilateur gcc 5.4.0 donne un message d'erreur:

test.c: Assembler messages: 
test.c:7: Error: bad or irreducible absolute expression 
test.c:7: Error: expecting scale factor of 1, 2, 4, or 8: got `$2' 

Puis-je changer le

"leal 2(%%ebx,%%eax,$2),%1" 

à

"leal 2(%%ebx,%%eax,2),%1" 

C'est o k. Cependant, est-ce que 2 $ n'est pas égal à 2?

+1

Dans cette syntaxe, le nombre doit être sans $, c'est la façon dont il est défini. Normalement $ signifierait une constante, mais puisque vous ne pouvez pas avoir autre chose qu'une constante spécifique dans le mode d'adressage, il n'utilise pas de préfixe pour dire que c'est une constante. –

+1

FYI, en claquant '% ebx' sans dire le compilateur (avec une contrainte de clobber) entraînera des résultats imprévisibles. (Eh bien, prévisible si vous lisez la sortie finale asm du compilateur avec 'gcc -O2 -S'). Voir https://stackoverflow.com/tags/inline-assembly/info –

Répondre

0

Dans AT & La syntaxe T, le signe dollar $ indique un opérande immédiat . Par exemple, il établit une distinction

add 16,%eax 

(ajouter de la valeur à l'adresse 16 à eax) de

add $16,%eax 

(ajouter 16 à eax). Notez que ceci n'est pas du tout lié aux constantes entières. Vous pourriez tout aussi bien bref

add foo,%eax 

et

add $foo,%eax 

foo est un symbole. La notation disp(base,index,scale) indique un opérande de mémoire utilisant l'adressage SIB . Chacune des trois pièces dans ce mode d'adressage a un but fixe, donc il ne sert à rien de décorer scale avec quoi que ce soit. Après tout, nous avons déjà choisi un mode d'adressage, alors pourquoi devrait-il y avoir un autre indicateur de type opérande entre parenthèses? Notez que le % devant les noms de registre est toujours obligatoire car il distingue le nom de registre d'un nom de macro ou de symbole.