2

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

例如:

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

我知道这"r"告诉编译器使用寄存器来保存 的值x,但是什么时候使用"g"or更合适"m""m"由于我使用的是注册目的地,因此会使用破坏此代码;并且"g"操作数约束过于“模糊”?

4

1 回答 1

9

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

如果你有mov %0, 4(%%esp),那么你不能允许%0成为内存引用,因为4(%%esp)是内存引用,并且没有mov接受两个内存引用的指令形式。所以你需要使用一个约束,比如r要求%0成为一个寄存器。

(请注意,这段代码本身是无用的。一旦asm完成,编译器就可以随意使用%eax它想要的任何东西,因此没有理由期望它x会保留在寄存器中。将某些东西移动到%eax仅在%eax在允许编译器再次控制之前使用的一系列指令。)

于 2013-04-03T15:05:30.987 回答