我很难理解 GCC 内联汇编 (x86) 中的角色约束。我有阅读手册 http://gcc.gnu.org/onlinedocs/gcc/Constraints.html#Constraints,它准确地解释了每个约束的作用。问题是,尽管我了解每个约束的作用,但我对为什么要使用一个约束而不是另一个约束,或者可能的含义知之甚少。
我意识到这是一个非常广泛的主题,所以一个小例子应该有助于缩小焦点。以下是一个简单的 asm 例程,仅将两个数字相加。如果发生整数溢出,则写入一个值1
到输出 C 变量。
int32_t a = 10, b = 5;
int32_t c = 0; // overflow flag
__asm__
(
"addl %2,%3;" // Do a + b (the result goes into b)
"jno 0f;" // Jump ahead if an overflow occurred
"movl $1, %1;" // Copy 1 into c
"0:" // We're done.
:"=r"(b), "=m"(c) // Output list
:"r"(a), "0"(b) // Input list
);
现在这工作得很好,除了我必须任意摆弄约束,直到它正常工作为止。最初,我使用了以下约束:
:"=r"(b), "=m"(c) // Output list
:"r"(a), "m"(b) // Input list
请注意,我使用“m”约束代替“0”b
。这有一个奇怪的副作用,如果我使用优化标志进行编译并调用该函数两次,由于某种原因,加法操作的结果也会存储在c
。我最终读到了“匹配约束 http://www.ibm.com/developerworks/library/l-ia.html”,它允许您指定一个变量既用作输入操作数又用作输出操作数。当我更改时"m"(b)
to "0"(b)
有效。
但我真的不明白为什么你会使用一个约束而不是另一个。我的意思是,是的,我明白“r”意味着变量应该在寄存器中,“m”意味着它应该在内存中 - 但我不知道really了解选择一个而不是另一个的含义是什么,或者如果我选择某种约束组合,为什么加法运算无法正常工作。
问题: 1)在上面的示例代码中,为什么“m”约束对b
cause c
写信给? 2)是否有任何教程或在线资源可以更详细地介绍约束?