由于本地标签,AIX汇编程序出现1252-142语法错误 [英] 1252-142 Syntax error from AIX assembler due to local label

查看:164
本文介绍了由于本地标签,AIX汇编程序出现1252-142语法错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用内联汇编和本地标签时,出现汇编错误。编译器为GCC,计算机为运行AIX的PowerPC。代码读取时间戳(大约等于 rdtsc ):

I'm catching an assembler error when using inline assembly and a local label. The compiler is GCC, and the machine is PowerPC running AIX. The code reads the timestamp (it is roughly equivalent to rdtsc):

static unsigned long long cpucycles( void )
{
  unsigned long long int result=0;
  unsigned long int upper, lower,tmp;
  __asm__ __volatile__ (
                "0:             \n\t"
                "mftbu   %0     \n\t"
                "mftb    %1     \n\t"
                "mftbu   %2     \n\t"
                "cmpw    %2,%0  \n\t"
                "bne-    0b     \n\t"
                : "=r"(upper),"=r"(lower),"=r"(tmp)
                : :
                );
  result = upper;
  result = result<<32;
  result = result|lower;
  return(result);
}

汇编代码后,结果为:

gcc -O3 -Wall -Wextra -mcpu=power8 -maltivec test.c -o test.exe
Assembler:
test.s: line 103: 1252-142 Syntax error.

使用-保存温度和检查 test.s

$ cat -n test.s
...

   101  L..5:
   102   # 58 "test.c" 1
   103          0:
   104          mftbu   10
   105          mftb    9
   106          mftbu   8
   107          cmpw    8,10
   108          bne     0b
   109

看起来汇编器在使用本地标签时遇到了麻烦。基于IBM的使用内联汇编和本地标签我认为标签和分支的使用正确:

It looks like the assembler is having trouble with the local label. Based on IBM's Use of inline assembly and local labels I believe the label and branch are being used correctly:


仅某些本地标签在内联汇编中合法。您可能会看到
标签,例如代码C中的0和1。它们是
指令 bne-0b\n\t 和 bne 1f\n\t 。 (
标签的后缀f表示分支指令后面的标签,b代表前面的
)。

Only some local labels are legal in inline assembly. You might see labels, such as 0 and 1 in Code C. They are the branching target of instruction bne- 0b\n\t and bne 1f\n\t. (The f suffix for the label means the label behind the branch instruction, and b is for the one ahead)

IBM的错误1252-142的消息并不是很有帮助:

IBM's error message for 1252-142 is not very helpful:


原因

如果汇编处理中发生错误,并且该错误不是消息目录中定义的
,则使用此通用错误消息。
此消息涵盖伪操作和指令。因此,
的使用情况声明将毫无用处。

If an error occurred in the assembly processing and the error is not defined in the message catalog, this generic error message is used. This message covers both pseudo-ops and instructions. Therefore, a usage statement would be useless.

操作

确定意图和源代码行的构造,然后查阅
的特定说明文章以更正源代码行。

Determine intent and source line construction, then consult the specific instruction article to correct the source line.

什么是问题以及如何解决?

What is the problem and how do I fix it?

基于@Eric在评论中的建议:

Based on @Eric's suggestions in the comments:

__asm__ __volatile__ (
  "\n0:           \n\t"
  "mftbu   %0     \n\t"
  "mftb    %1     \n\t"
  "mftbu   %2     \n\t"
  "cmpw    %2,%0  \n\t"
  "bne-    0b     \n\t"
  : "=r"(upper),"=r"(lower),"=r"(tmp)
);

导致下移一行的问题:

gcc -O3 -Wall -Wextra -mcpu=power8 -maltivec test.c -o test.exe
Assembler:
test.s: line 104: 1252-142 Syntax error.

但是标签似乎在第0列中:

But it looks like the label is in column 0:

 103
 104  0:
 105          mftbu   10
 106          mftb    9
 107          mftbu   8
 108          cmpw    8,10
 109          bne-    0b


推荐答案

gcc不直接发出机器代码;它将其asm输出提供给系统汇编程序。您可以将gcc配置为使用其他汇编程序,例如GAS,但显然您使用的计算机上的默认设置是使用AIX汇编程序的GCC。

gcc doesn't emit machine-code directly; it feeds its asm output to the system assembler. You could configure gcc to use a different assembler, like GAS, but apparently the default setup on the machine you're using has GCC using AIX's assembler.

显然,AIX的汇编程序没有与GNU汇编程序不同,它不支持数字标签。当您链接的文章提到使用诸如 0 之类的标签时,您链接的文章可能是Linux(偶然或故意)。

Apparently AIX's assembler doesn't support numeric labels, unlike the GNU assembler. Probably that article you linked is assume Linux (accidentally or on purpose) when it mentions using labels like 0.

最简单的解决方法可能是让GCC自动为标签编号,而不是使用本地标签,因此可以在没有符号名称的情况下在同一编译单元中多次内联/展开同一asm块冲突。 %= 在每个实例中扩展为唯一的数字。

The easiest workaround is probably having GCC auto-number the label instead of using local labels, so the same asm block can be inlined / unrolled multiple times in the same compilation unit without symbol-name conflicts. %= expands to a unique number in every instance.

IDK如果 L .. 使其成为文件本地标签(不会使调试信息或符号表混乱)。在Linux / ELF / x86上, .L 是常规前缀,但是您有编译器生成的 L .. 标签。

IDK if an L.. makes it a file-local label (which won't clutter up debug info or the symbol table). On Linux/ELF/x86, .L is the normal prefix, but you have a compiler-generated L.. label.

__asm__ __volatile__ (
            "L..again%=:    \n\t"
            "mftbu   %0     \n\t"
            "mftb    %1     \n\t"
            "mftbu   %2     \n\t"
            "cmpw    %2,%0  \n\t"
            "bne-    L..again%="
            : "=r"(upper),"=r"(lower),"=r"(tmp)
            : :
            );

或者对于这个特定的asm用例,可能有一个内置函数可以读取时间-stamp寄存器可以像这样编译成asm。

Or for this specific asm use-case, there might be a built-in function that reads the time-stamp registers which would compile to asm like this.

这篇关于由于本地标签,AIX汇编程序出现1252-142语法错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆