error: unknown "%" symbol on SPARC

error: unknown "%" symbol on SPARC

我的程序在 Ubuntu 上运行良好。

在Solaris SPARC系统上用gcc编译时遇到错误

我有几段代码:

printf("endian_convert: %s\n", endian_convert);

asm("movl , %esi\n\t"
                "movl $.LC0, %edi\n\t"
                "movl [=10=], %eax");

这是我在 SPARC 上遇到的错误:

gcc -g -Wall -Werror -pedantic -Wextra src/utfconverter.c -o bin/utf 

/usr/ccs/bin/as: "/var/tmp//cc9czJEf.s", line 957: error: unknown "%"-symbol
/usr/ccs/bin/as: "/var/tmp//cc9czJEf.s", line 957: error: statement syntax
.......
/usr/ccs/bin/as: "/var/tmp//cc9czJEf.s", line 1058: error: unknown "%"-symbol
/usr/ccs/bin/as: "/var/tmp//cc9czJEf.s", line 1058: error: statement syntax
*** Error code 1 make: Fatal error: Command failed for target `utf'

所以,“%”符号在 SPARC 上被认为是未知的?

如何解决这个问题并使其在 SPARC 上运行?

(问题的原版没有提到错误来自SPARC Solaris系统,只是将其称为C90,因为其上安装的旧版本gcc默认为-std=c90,导致关于 C90 中非法事物的错误消息。)


等一下,"works fine on Ubuntu but not on C90"? /usr/ccs/bin/as(在您的屏幕截图中)看起来像 Solaris。这 + 主机名是一个线索,表明这可能是一台 SPARC 机器,根本不是 x86。


显然 x86 汇编不是有效的 SPARC 汇编语法。这是一个不同的 CPU 架构。

如果您使用 gcc foo.c -S 并查看生成的 foo.s asm 输出文件,您会发现它充满了 SPARC asm,除了由您的 asm 语句。

SPARC 语法确实在寄存器名称上使用了 % 修饰符,但寄存器名称不同。例如add %i0, %i1, %o0 将输入寄存器 i0i1 相加,将结果存储在输出寄存器 o0 中。 (在函数 arg 中输入,在函数结果中输出。SPARC uses a sliding window onto a large virtual register file 可能会或可能不会溢出到内存,具体取决于 CPU 微体系结构在 save 指令运行时是否超出寄存器.)

请记住,这些错误来自 Solaris 汇编器,而不是来自 gcc。您使用的是 gcc,但它使用的是系统汇编程序而不是 GNU 汇编程序。

无论如何,我建议将您的代码重写为纯可移植的 C,而不是使用 #ifdef __x86__ 继续使用该内联汇编,或编写它的 SPARC 端口。


顺便说一句,您的 asm 语句看起来很糟糕。不同版本的 gcc 可能会在 .LC0 处存储不同的常量,从而破坏您的代码。更重要的是,您没有使用 input/output 约束来告诉编译器什么值在哪里。如果您假设可以在函数内部的 asm 中设置 eax,那是不正确的。该函数可以并且将会内联,然后您的 asm 就在您的函数内联的任何地方自由浮动。请参阅 以获取一些 GNU C 内联汇编教程的链接。

此外,您不需要内联汇编来进行字节序转换。您将通过使用 endian.h functions 获得更好的 asm,例如 uint32_t le32toh(uint32_t little_endian_32bits);,它使用 gcc 内置函数或内联 asm 来让编译器自己生成最佳汇编输出。

另请参阅 https://gcc.gnu.org/wiki/DontUseInlineAsm,即使您 知道如何正确使用它也适用。