【问题标题】:Writing inline assembly in a separate .S file在单独的 .S 文件中编写内联汇编
【发布时间】:2018-05-03 16:43:06
【问题描述】:

由于对另一个问题的建议,我试图将我的汇编代码与我的 C 代码分开,但我收到了这个错误:

arm-linux-gnueabihf-gcc -O0 -g3 -Wall -c -fmessage-length=0 -mfpu=neon -o src/ASM.o ../src/ASM.c 
In file included from ../src/ASM.c:1:0:
../src/asm.S:1:12: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘:’ token
 mul64x64asm:
      ^

我尝试将分号放在一堆地方,但它并没有解决我的问题,即使它与这个问题无关,我们也感谢任何帮助。 这是我的 ASM.c 和 asm.S 文件:

ASM.c

#include "asm.S"

int main(void) {
    extern  void mul64x64asm();
    mul64x64asm();
    return 1;

}

asm.S

mul64x64asm:
      MOVW R0,0x12f4
      MOVT R0,0x5678

更新: 我尝试了建议的答案并最终得到了这个

arm-linux-gnueabihf-as -g --gstabs -o src/asm.o ../src/asm.S 
arm-linux-gnueabihf-gcc -O0 -g3 -Wall -c -fmessage-length=0 -mfpu=neon -o src/ASM.o ../src/ASM.c 
arm-linux-gnueabihf-gcc -o ASM src/ASM.o src/asm.o ../src/asm.S 
src/ASM.o: In function `main':
/home/yunus/eclipse-workspace/ASM/Debug/../src/ASM.c:4: undefined reference to `mul64x64asm'
collect2: error: ld returned 1 exit status

我认为 eclipse 正在将 asm.S 和 ASM.c 编译成对象并将它们链接到这里。

更新 2: 所以我按照@fuz 的指示修改了我的 asm.S 文件 asm.S

.globl mul64x64asm
mul64x64asm:
          MOVW R0,0x12f4
          MOVT R0,0x5678

我想用尽可能少的代码来完成这项工作,所以我删除了 .size 符号。

../src/asm.S:2: Error: unrecognised symbol type ""

删除了类型符号,我现在收到此错误:

arm-linux-gnueabihf-as -g --gstabs -o src/asm.o ../src/asm.S 
arm-linux-gnueabihf-gcc -o ASM src/ASM.o src/asm.o ../src/asm.S 
/tmp/ccYM9smZ.o: In function `mul64x64asm':
(.text+0x0): multiple definition of `mul64x64asm'
src/asm.o:../src/asm.S:3: first defined here
collect2: error: ld returned 1 exit status

从 Eclipse 的链接器配置中删除了我的 asm.S 文件,因此它不会在此行中链接:

arm-linux-gnueabihf-gcc -o ASM src/ASM.o src/asm.o ../src/asm.S

终于让它工作了。感谢大家的回答/cmets。

最终更新:为了在 Eclipse 中调试我的代码,我不得不在 asm.S 文件中包含更多行,这是我最终得到的最终版本:

.text
.globl mul64x64asm
.type mul64x64asm,%function 
mul64x64asm:
           mov r0, #2
           mov r1, #3
           bx lr
           .size mul64x64asm,.-mul64x64asm

【问题讨论】:

  • 而不是#includeing 您的汇编代码,您应该单独汇编它并将生成的目标文件链接到最终的二进制文件中。您应该包含一个在汇编代码中声明全局符号的标头。
  • 你不能把它们链接在一起吗?
  • 我也尝试在不包含的情况下将它们链接在一起,但最终出现未定义的引用错误@klutt
  • 在您之前的问题中,您没有被指示include 像这样的单独 asm 文件。评论的人建议您创建一个单独的 asm 文件 - 这意味着您将其组装为目标文件,然后链接到它。
  • @YunusGulcu 您收到未定义的引用错误,因为您忘记将 mul64x64asm 设置为全局符号。有关如何执行此操作,请参阅汇编器手册。

标签: c eclipse assembly arm raspberry-pi3


【解决方案1】:

你快到了。要将用汇编编写的函数添加到您的程序中,请将其放在一个单独的文件中。

确保将您想在程序其他地方使用的所有符号标记为全局符号,以便链接器在链接时考虑它们:

    .globl mul64x64asm
    .type mul64x64asm,%function
mul64x64asm:
    MOVW R0,0x12f4
    MOVT R0,0x5678
    bx lr                        @ don't forget to return instead of fallthrough
    .size mul64x64asm,.-mul64x64asm

.globl 指令将符号可见性调整为全局。.type 指令将符号类型标记为函数,这在您使用动态链接时很重要。 .size 指令将 mul64x64asm 的符号大小设置为此处 (.) 与函数开头之间的差异。这对调试很有用,但如果你太懒,可以省略。

在非 ARM 上,将使用 .type mul64x64asm,@function,但 @ 是 ARM 上的注释字符,因此 gas 使用 %

现在组装它并将其链接到您的程序中,就像任何其他目标文件一样。

【讨论】:

    【解决方案2】:

    您应该从您的程序集中创建一个.o。然后你用类似的东西编译你的c代码:

    gcc main.c asm.o
    

    【讨论】:

      【解决方案3】:

      预处理器和#include 指令有点误导。它会将包含文件中的代码粘贴到执行#include 的文件中。

      预处理后,您的代码将类似于

      mul64x64asm:
            MOVW R0,0x12f4
            MOVT R0,0x5678
      
      int main(void) {
          extern  void mul64x64asm();
          mul64x64asm();
          return 1;
      
      }
      

      那肯定不是有效的 C 代码。

      如果你想做内联汇编,你必须以编译器理解的方式来做。 Find the documentation for your version of GCC,并阅读更多相关信息。

      另一个可能更好的选择是使用汇编程序将asm.S 源文件构建到目标文件中。然后将您的主程序与此目标文件链接以创建可执行程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-06
        • 2012-10-20
        • 2013-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多