Таким образом, он загружает r0 и r1 с 2 (ну, это делает плюс одна вещь в текущей задаче + 1
10648: e1a00003 mov r0, r3
1064c: e51b1010 ldr r1, [fp, #-16]
10650: eb00fd36 bl 4fb30 <____aeabi_uidivmod_veneer>
Я думаю, они использовали _veneer для переключения с руки на большой палец, это батут для переключения режимов:
0004fb30 <____aeabi_uidivmod_veneer>:
4fb30: e51ff004 ldr pc, [pc, #-4] ; 4fb34 <____aeabi_uidivmod_veneer+0x4>
4fb34: 00010905 .word 0x00010905
Это приведет вас к действию по модулю, это код большого пальца, режим большого пальца
00010904 <__aeabi_uidivmod>:
10904: 2900 cmp r1, #0
10906: d0f8 beq.n 108fa <__aeabi_uidiv+0x252>
10908: e92d 4003 stmdb sp!, {r0, r1, lr}
1090c: f7ff fecc bl 106a8 <__aeabi_uidiv>
10910: e8bd 4006 ldmia.w sp!, {r1, r2, lr}
10914: fb02 f300 mul.w r3, r2, r0
10918: eba1 0103 sub.w r1, r1, r3
1091c: 4770 bx lr
1091e: bf00 nop
Таким образом, выглядит нормальное деление, затем умножает результат и вычитает, например,
12345 % 100 = 12345 - ((12345/100)*100) = 12345 - (123*100) = 12345 - 12300 = 45
Интересно, проблема в режиме большого пальца? Arm1176 определенно имеет режим большого пальца, реальный, и я могу сделать большой палец.
Вы можете попробовать эксперимент, чтобы узнать сборку и ссылку:
.thumb
.thumb_func
.globl thumb_test
thumb_test:
add r0,#1
bx lr
arm-none-linux-gnueabi-as thumb_test.s -o thumb_test.o
или любой другой префикс цепочки инструментов, если он есть, и связать файл .o со всем остальным.
в коде C объявить его как
unsigned int thumb_test ( unsigned int );
и что бы вы ни передавали, вы должны получить это значение плюс один обратно ... попробуйте это вместо модуля.
Еще одна вещь, которую нужно попробовать - это просто прямое деление, посмотрите, работает ли деление, но не по модулю, может быть, проблема в инструкции умножения? Кто знает.
Хмммм, кажется, я вижу проблему:
0004fb30 <____aeabi_uidivmod_veneer>:
4fb30: e51ff004 ldr pc, [pc, #-4] ; 4fb34 <____aeabi_uidivmod_veneer+0x4>
4fb34: 00010905 .word 0x00010905
Вы не можете переключать режимы с помощью ldr, это должен быть bx или blx, он, вероятно, обращается к неопределенному обработчику, когда пытается выполнить код большого пальца в режиме охраны.
У меня есть несколько примеров того, как переключение режимов должно работать, в частности, написано для qemu. Теперь это низкоуровневый пример, например, нет printf, у меня есть вывод uart с возможностью видеть вещи на uart. Если это проблема (переключение в режим большого пальца), то вам нужно проверить, как вы компилируете и связываете свою программу. Возможно, вам потребуется указать взаимодействие, или вам может понадобиться понять, как была построена ваша цепочка инструментов, если вы не используете ранее цепочку инструментов исходного кода (в настоящее время используется наставником графики). при условии, что вы используете что-то на основе gnu / gcc.
Если у вас есть способ поместить туда неопределенный обработчик или если вы можете наблюдать за трассировкой и видеть, как компьютер падает на что-то рядом с адресом 0x0000000, что, вероятно, и происходит. Если вы соберете мою маленькую вещь thumb_test, и она использует ldr вместо bx, то это не должно работать, либо все равно должно произойти сбой ...