使用条件标志作为GNU C内联asm输出

时间:2015-05-19 00:33:49

标签: c gcc assembly inline-assembly

我正在研究一些代码,其中非常希望从内联asm块中获取条件标志输出,并将其用作在调用C代码中分支的条件。我不想存储标志(这将是无用的和低效的;已经有更有效的方法来实现结果)但是直接使用标志。有没有办法用GNU C内联asm约束来实现这个目的?我对可用于多指令集架构的方法感兴趣,目的是将它与架构的LL / SC样式原子产生的条件标志一起使用。当然另一个明显的用例(与我正在做的分开)是允许外部C代码从内联asm中的操作分支进位标志的结果。

3 个答案:

答案 0 :(得分:3)

从x86上的GCC6开始,您实际上可以使用"=@ccCOND"作为输出(其中COND是任何有效的x86条件代码)。

示例originally from here,由David的建议清理:

int variable_test_bit(long n, volatile const unsigned long *addr)
{
    int oldbit;
    asm volatile("bt %[value],%[bit]"
                 : "=@ccc" (oldbit)
                 : [value] "m" (*addr), [bit] "Jr" (n));
    return oldbit;
}

在使用之前,您应该测试是否定义了__GCC_ASM_FLAG_OUTPUTS__

Documentation at https://gcc.gnu.org

答案 1 :(得分:1)

我有一个部分解决方案,但我并不喜欢它,因为它需要将分支指令放在asm中,并且因为它需要一个非常难看的GCC功能,其他" GNU C兼容&#34 ;编译器可能不支持:asm goto。但它确实可以消除asm之外的分支。这个想法是:

static inline int foo(...)
{
    __asm__ goto ( " .... ; cond_jmp %l[ret0]" : : "r"(...) ... 
                   : "clobbers" : ret0 );
    return 1;
ret0:
    return 0;
}

当内联到if (foo(...)) ... else ...的调用者时,asm块中的条件跳转最终直接指向else分支,即使在抽象机级别还有涉及的返回值。

答案 2 :(得分:0)

不幸的是,GCC不支持访问asm语句之外的条件标志。如果您不想设置值,那么您必须将条件分支移动到asm语句中。这意味着要么使用您已经发现的asm goto labels,要么将分支目标纳入您的asm语句。

您可能还想检查GCC的旧样式__sync atomic builtins或较新的memory model based atomics是否提供您想要的功能,而不是您正在使用的原子指令。