2017-09-24 165 views
0

这是第一次我写汇编代码。 在第一个开始,我写了

#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; 
} 

的GCC 5.4.0编译器会发出错误信息:

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' 

然后我改变了

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

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

它是o ķ。但是,2美元不等于2?

+1

在此语法的数量必须是没有$,这就是它只是如何定义的。通常情况下$意味着一个常量,但由于在寻址模式中除了特定的常量外没有别的东西,所以它不会使用前缀来表示这是一个常量。 –

+1

仅供参考,不重挫告诉编译器(带撞约束)'%ebx'将导致不可预知的结果。 (好吧,如果你用'gcc -O2 -S'从编译器中读取最终的asm输出结果是可以预测的)。请参阅https://stackoverflow.com/tags/inline-assembly/info –

回答

0

在AT & T语法中,美元符号$表示一个立即数操作数。例如,它区分

add 16,%eax 

add $16,%eax 

(在地址16增值eax)(添加16eax)。请注意,这与整数常量无关。你也可以同样令状

add foo,%eax 

add $foo,%eax 

其中foo是一些符号。 disp(base,index,scale)表示使用SIB寻址的存储器操作数。每三块在这种寻址模式有一个固定的目的,所以在与任何装饰scale没有意义的。毕竟,我们已经选择了一种寻址模式,为什么在括号内应该有另一个操作数类型的指示器呢?请注意,寄存器名称前面的%仍然是强制性的,因为它将寄存器名称与宏或符号名称区分开来。