在单独的 .S 文件中编写内联汇编
Writing inline assembly in a separate .S file
由于对另一个问题的建议,我试图将我的汇编代码与我的 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
终于成功了。感谢大家的 answers/comments.
最终更新:为了在 eclipse 中调试我的代码,我不得不在 asm.S 文件中包含更多行,这是我最终得到的最终版本:
.text
.globl mul64x64asm
.type mul64x64asm,%function
mul64x64asm:
mov r0, #2
mov r1, #3
bx lr
.size mul64x64asm,.-mul64x64asm
预处理器和 #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
源文件构建到目标文件中。然后link你的主程序用这个目标文件创建可执行程序。
你应该从你的程序集中制作一个 .o
。然后你用类似的东西编译你的c代码:
gcc main.c asm.o
你快到了。要将用汇编语言编写的函数添加到您的程序中,请像您所做的那样将它放在一个单独的文件中。
确保将您要在程序其他地方使用的所有符号标记为全局符号,以便 linker 在 linking:
时考虑它们
.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
指令将符号类型标记为函数, 这在您使用动态 linking 时很重要。 .size
指令将 mul64x64asm
的符号大小设置为此处 (.
) 与函数开头之间的差值。这对调试很有用,但如果你太懒,可以省略。
在非 ARM 上,将使用 .type mul64x64asm,@function
,但 @
是 ARM 上的注释字符,因此 gas 使用 %
代替。
现在 assemble 这个和 link 它像任何其他目标文件一样进入您的程序。
由于对另一个问题的建议,我试图将我的汇编代码与我的 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
终于成功了。感谢大家的 answers/comments.
最终更新:为了在 eclipse 中调试我的代码,我不得不在 asm.S 文件中包含更多行,这是我最终得到的最终版本:
.text
.globl mul64x64asm
.type mul64x64asm,%function
mul64x64asm:
mov r0, #2
mov r1, #3
bx lr
.size mul64x64asm,.-mul64x64asm
预处理器和 #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
源文件构建到目标文件中。然后link你的主程序用这个目标文件创建可执行程序。
你应该从你的程序集中制作一个 .o
。然后你用类似的东西编译你的c代码:
gcc main.c asm.o
你快到了。要将用汇编语言编写的函数添加到您的程序中,请像您所做的那样将它放在一个单独的文件中。
确保将您要在程序其他地方使用的所有符号标记为全局符号,以便 linker 在 linking:
时考虑它们 .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
指令将符号类型标记为函数, 这在您使用动态 linking 时很重要。 .size
指令将 mul64x64asm
的符号大小设置为此处 (.
) 与函数开头之间的差值。这对调试很有用,但如果你太懒,可以省略。
在非 ARM 上,将使用 .type mul64x64asm,@function
,但 @
是 ARM 上的注释字符,因此 gas 使用 %
代替。
现在 assemble 这个和 link 它像任何其他目标文件一样进入您的程序。