首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GCC内嵌装配:约束条件

GCC内嵌装配:约束条件
EN

Stack Overflow用户
提问于 2010-10-10 02:03:48
回答 1查看 7.1K关注 0票数 21

我很难理解GCC内联程序集(x86)中的角色约束。我有阅读手册,它准确地解释了每个约束所做的事情。问题是,尽管我理解每个约束的作用,但对于为什么您会使用一个约束而不是另一个约束,或者可能会产生什么影响,我的理解非常有限。

我意识到这是一个非常广泛的话题,所以一个小的例子应该有助于缩小重点。下面是一个简单的asm例程,它只添加两个数字。如果发生整数溢出,则将值1写入输出C变量。

代码语言:javascript
复制
 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
 );

现在,这很好,除了我不得不任意摆弄约束,直到我使它正确工作。最初,我使用了以下约束:

代码语言:javascript
复制
  :"=r"(b), "=m"(c)    // Output list
  :"r"(a), "m"(b)     // Input list

请注意,对于b,我使用的不是"0",而是"m“约束。这有一个奇怪的副作用,如果我用优化标志编译并两次调用函数,由于某种原因,添加操作的结果也会存储在c中。我最终读到了"匹配约束",它允许您指定变量同时用作输入和输出操作数。当我将"m"(b)改为"0"(b)时,它起了作用。

但我真的不明白为什么你会用一个约束来代替另一个约束。我的意思是,是的,我理解"r“表示变量应该在寄存器中,"m”表示应该在内存中--但我并不真正理解选择一个而不是另一个的含义,或者如果选择某种约束组合,加法操作为什么不能正确工作。

问题: 1)在上面的示例代码中,为什么b上的"m“约束会导致c被写入?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-10-10 02:15:04

下面是一个更好地说明为什么您应该谨慎选择约束的例子(与您的函数相同,但可能编写得更简洁一些):

代码语言:javascript
复制
bool add_and_check_overflow(int32_t& a, int32_t b)
{
    bool result;
    __asm__("addl %2, %1; seto %b0"
            : "=q" (result), "+g" (a)
            : "r" (b));
    return result;
}

因此,使用的约束是:qrg

  • q意味着只能选择eaxecxedxebx。这是因为set*指令必须写入8位可寻址寄存器(alah,.)。b%b0中的使用意味着,使用最低的8位部分(alcl,.).
  • 对于大多数双操作数指令,至少有一个操作数必须是寄存器.因此,两种操作数都不要使用mg;至少对其中一个操作数使用r
  • 对于最后一个操作数,不管它是寄存器还是内存,所以使用g (general)。

在上面的示例中,我选择使用g (而不是r)作为a,因为引用通常是作为内存指针实现的,因此使用r约束需要先将引用复制到寄存器,然后再复制回来。使用g,可以直接更新引用。

至于原始版本为什么用加法值覆盖c,这是因为您在输出槽中指定了=m,而不是(例如) +m;这意味着编译器可以重用相同的内存位置进行输入和输出。

在您的示例中,这意味着两种结果(因为bc使用了相同的内存位置):

  • 添加没有溢出:然后,cb的值覆盖(添加的结果)。
  • 添加溢出:然后,c变成1( b也可能变成1,这取决于代码是如何生成的)。
票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3898704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档