何时在扩展GCC内联汇编中使用特定操作数约束?

时间:2013-04-03 14:54:47

标签: c gcc assembly x86 inline-assembly

我很难理解何时在扩展GCC内联汇编中使用特定输入操作数约束而不是另一个。

例如:

int x = 42;
asm("movl %0, %%eax;"
    : /* no outputs */
    : "r"(x)
    : "%eax");

我知道"r"告诉编译器使用寄存器保持x的值,但何时更适合使用"g""m"?因为我正在使用寄存器目的地,所以使用"m"会破坏此代码;而且"g"会对操作数约束过于“模糊”吗?

1 个答案:

答案 0 :(得分:7)

您使用的大部分约束是它所描述的类型是否适用于您的说明。在mov %0, %%eax中,您可以放置​​寄存器,内存引用或立即操作数来代替%0,汇编器将接受它。因此,您可以使用g作为约束。

如果您有mov %0, 4(%%esp),那么您不能允许%0成为内存引用,因为4(%%esp)是内存引用,并且没有mov的形式接受两个内存引用的指令。因此,您需要使用r之类的约束来要求%0成为注册。

(请注意,此代码本身是无用的。只要asm完成,编译器就可以自由地使用%eax,因此没有理由期望{ {1}}将保留在寄存器中。只有在允许编译器再次控制之前使用x的一系列指令中,将某些内容移动到%eax才有用。)