Таким образом, он загружает 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 определенно есть режим большого пальца, настоящий, и я qemu могу сделать большой палец.
Вы можете провести эксперимент, чтобы узнать, как ассемблировать и связывать:
.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, чтобы добраться туда, то это не должно работать, либо все равно должно произойти сбой...
person
old_timer
schedule
02.02.2012