我很难理解何时在扩展的 GCC 内联汇编中使用特定的输入操作数约束而不是另一个。
例如:
int x = 42;
asm("movl %0, %%eax;"
: /* no outputs */
: "r"(x)
: "%eax");
我知道这"r"
告诉编译器使用寄存器来保存 的值x
,但是什么时候使用"g"
or更合适"m"
?"m"
由于我使用的是注册目的地,因此会使用破坏此代码;并且"g"
操作数约束过于“模糊”?
我很难理解何时在扩展的 GCC 内联汇编中使用特定的输入操作数约束而不是另一个。
例如:
int x = 42;
asm("movl %0, %%eax;"
: /* no outputs */
: "r"(x)
: "%eax");
我知道这"r"
告诉编译器使用寄存器来保存 的值x
,但是什么时候使用"g"
or更合适"m"
?"m"
由于我使用的是注册目的地,因此会使用破坏此代码;并且"g"
操作数约束过于“模糊”?
您使用的约束的很大一部分是它所描述的类型是否适用于您的说明。在mov %0, %%eax
中,您可以将寄存器、内存引用或立即操作数代替%0
,汇编器将接受它。所以你可以使用g
约束。
如果你有mov %0, 4(%%esp)
,那么你不能允许%0
成为内存引用,因为4(%%esp)
是内存引用,并且没有mov
接受两个内存引用的指令形式。所以你需要使用一个约束,比如r
要求%0
成为一个寄存器。
(请注意,这段代码本身是无用的。一旦asm
完成,编译器就可以随意使用%eax
它想要的任何东西,因此没有理由期望它x
会保留在寄存器中。将某些东西移动到%eax
仅在%eax
在允许编译器再次控制之前使用的一系列指令。)