代码之家  ›  专栏  ›  技术社区  ›  user48956

汇编错误(GCC4.2.4=win,GCC4.3.3=fail)

  •  2
  • user48956  · 技术社区  · 15 年前

    我们最近将代码升级到 gcc4.3.3 gcc4.2.4 .

    void testAndSet(  volatile int*  s, int* val )
    {
       __asm__ __volatile__ ( "btsl   $0, %0\n   "
               "jc   bitSet\n   "
               "movl   $0, %1\n   "
               "jmp   returnVector\n"
               "bitSet:\n   "
               "movl   $1, %1\n"
               "returnVector: " : "=m"(*s), "=m"(*val) );
    }
    

    我们的代码现在由于以下错误而失败,

    lock.cxx: Assembler messages:
    lock.cxx:59: Error: symbol `bitSet' is already defined
    lock.cxx:61: Error: symbol `returnVector' is already defined
    lock.cxx:59: Error: symbol `bitSet' is already defined
    lock.cxx:61: Error: symbol `returnVector' is already defined
    

    那些符号在其他地方找不到。(重命名它们会导致与新名称相同的错误)。

    这是怎么回事?为什么我会得到两次错误?

    3 回复  |  直到 9 年前
        1
  •  10
  •   user9876    15 年前

    可能优化器已经更改,现在正在将testandset()函数内联到2个位置。因为标签使用的是全局名称,所以这不起作用。您应该改为使用本地名称。例如:

       __asm__ __volatile__ ( "btsl   $0, %0\n   "
               "jc   0f\n   "
               "movl   $0, %1\n   "
               "jmp   1f\n"
               "0:\n   "
               "movl   $1, %1\n"
               "1: " : "=m"(*s), "=m"(*val) );
    

    本地标签只是数字;要消除有许多名为“0”的标签的情况,需要使用 jmp 0f “向前跳跃和” jmp 0b “向后跳跃。

        2
  •  5
  •   Adam Rosenfield    15 年前

    这与您的错误无关,但是您可以通过使用 setCC instruction :

       __asm__ __volatile__ ( "btsl   $0, %0\n   "
           "mov $0, %1\n"
           "setc %1\n" : "=m"(*s), "=m"(*val) );
    

    这个 setCC 指令(其中cc是条件代码标志之一,类似于 jCC 指令)根据给定条件是否满足,将字节设置为0或1。由于目标是一个4字节的值,因此需要使用0预加载它,或者使用 MOVZX instruction 使上3个字节为0。

        3
  •  2
  •   demiurg_spb    9 年前

    也可以通过添加 %= 在每个本地标签之后:

    “循环%=:”“\n\t”