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