问题描述
使用内联汇编和本地标签时,出现汇编错误。编译器为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:
IBM的并不是很有帮助:
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语法错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!