我正在尝试在裸机架构上开发一个程序(使用ARM cortex-m4f处理器的stm32f4板)。我在ABI调用__aebi_idivmod时遇到了一个奇怪的问题。 调用是由编译器生成的,因为在代码中有多个%操作数的使用。奇怪的是,如果我查看使用objdump编译生成的.elf的转储,我得到的是:
080080e0 <__aeabi_idivmod>:
80080e0: e3510000 cmp r1, #0
80080e4: 0afffff9 beq 80080d0 <.divsi3_skip_div0_test+0x110>
80080e8: e92d4003 push {r0, r1, lr}
80080ec: ebffffb3 bl 8007fc0 <.divsi3_skip_div0_test>
80080f0: e8bd4006 pop {r1, r2, lr}
80080f4: e0030092 mul r3, r2, r0
80080f8: e0411003 sub r1, r1, r3
80080fc: e12fff1e bx lr
另一方面,当我在电路板上运行程序时,如果我使用gdb查看实际的ABI调用代码,我得到:
(gdb) disas __aeabi_idivmod
Dump of assembler code for function __aeabi_idivmod:
0x080080e0 <+0>: movs r0, r0
0x080080e2 <+2>: b.n 0x8008788
0x080080e4 <+4>: ; <UNDEFINED> instruction: 0xfff90aff
0x080080e8 <+8>: ands r3, r0
0x080080ea <+10>: stmdb sp!, {r0, r1, r4, r5, r7, r8, r9, r10, r11, r12, sp, lr, pc}
0x080080ee <+14>: ; <UNDEFINED> instruction: 0xebff4006
0x080080f2 <+18>: ldmia.w sp!, {r1, r4, r7}
0x080080f6 <+22>: b.n 0x8008100 <__aeabi_ldiv0>
0x080080f8 <+24>: asrs r3, r0, #32
0x080080fa <+26>: b.n 0x8008180 <K+120>
0x080080fc <+28>: vrhadd.u16 d14, d14, d31
End of assembler dump.
代码的位置对应,但是完全错误:有两条指令甚至不被gdb和第二条指令识别:
0x080080e2 <+2>: b.n 0x8008788
跳出进程的.text部分,结尾为0x866c:
Loading section .text, size 0x866c lma 0x8000000
关于我做错的任何线索?任何帮助将不胜感激。
编辑:我正在使用这个编译器:https://launchpad.net/gcc-arm-embedded/+download
arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.8.3 20131129 (release) [ARM/embedded-4_8-branch revision 205641]
EDIT2(遵循Notlikethat的回复):我用来链接我的程序的命令是:
$(ARMGNU)-ld -o program.gcc.thumb.elf -T memmap vectors.o program.gcc.thumb.o $(OBJS2) $(LIBGCC)
memmap是链接器脚本,vectors.o包含启动代码,$(OBJS2)包含必须链接在一起的所有目标文件,$(LIBGCC)是引用包含我们正在讨论的ABI调用的库的变量。根据我对Notlikethat的评论的理解,我应该在这里添加一些选项,强制将libgcc编译为thumb代码而不是normale ARM代码。我试图在链接器中添加这些选项,但在这两种情况下我都遇到了同样的错误:
arm-none-eabi-ld: unrecognised emulation mode: cpu=cortex-m3
Supported emulations: armelf
EDIT3:我只是在这一刻才意识到我的电路板的处理器是cortex-m4f而不是cortex-m3。我认为这不应该有太大的不同。
答案 0 :(得分:0)
问题在于,默认情况下,您的工具链将其标准库编译为ARM指令 - 由于Cortex-M处理器仅支持Thumb-2 *,因此在尝试使用ARM代码的交互分支时会出错。 / p>
现在,-mthumb
选项告诉编译器将你的代码编译成Thumb - 标准库是预编译的,甚至不会进入图片直到链接时间。幸运的是,the readme表示工具链已启用多工具库,因此您可以选择合适的库而无需查找特定于v7-M的工具链。
根据我对multilib内部工作原理的理解,你必须提供它正在寻找的精确魔术组合,在这种情况下可以是:
-mthumb -mcpu=cortex-m4
或:
-mthumb -march=armv7e-m
这将导致GCC为链接器提供一个适当兼容的库而不是默认值(如果您还需要浮点支持,还有文档中列出的其他选项)。
如果您正在使用单独的链接步骤,我相信您需要使用gcc
作为链接命令来代替ld
以使multilib正常工作 - 这当然是肯定的我在这里的Linaro工具链的情况(它只有双向硬浮/ ARMv4 + soft-float multilib)。
*严格,不完全是Thumb-2