Я пытаюсь разработать программу на голой металлической архитектуре (плата stm32f4 с процессором ARM cortex-m4f). У меня возникла странная проблема с вызовом ABI __aebi_idivmod. Вызов генерируется компилятором, потому что в коде есть многократное использование операнда %. Странно то, что если я смотрю на дамп .elf, сгенерированный компиляцией с использованием objdump, я получаю следующее:
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
С другой стороны, когда я запускаю программу на плате, если я смотрю на фактический код вызова ABI с помощью gdb, я получаю:
(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, который мы обсуждаем. Из того, что я понял из комментария Notlike, я должен добавить сюда какую-то опцию, чтобы принудительно компилировать код libgcc для просмотра вместо нормального кода ARM. Я пытался добавить в компоновщик эти параметры, но в обоих случаях получаю одну и ту же ошибку:
arm-none-eabi-ld: unrecognised emulation mode: cpu=cortex-m3
Supported emulations: armelf
EDIT3: только в этот момент я понял, что процессор моей платы - cortex-m4f, а не cortex-m3. Я не думаю, что это не должно сильно отличаться.