我正在尝试在裸机架构(带有 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
正在跳出以 0x866c 结束的进程的 .text 部分:
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 调用的库的变量。根据我从 Notlike 的评论中了解到的情况,我应该在这里添加一些选项,以强制将 libgcc 编译为拇指代码而不是普通的 ARM 代码。我试图将这些选项添加到链接器中,但在这两种情况下我都会遇到相同的错误:
arm-none-eabi-ld: unrecognised emulation mode: cpu=cortex-m3
Supported emulations: armelf
EDIT3:我只是在这一刻才意识到我的主板处理器是 cortex-m4f 而不是 cortex-m3。我认为这不应该有太大的不同。