2012-02-02 2 views
3

Когда я пытаюсь использовать% в C-коде в моей ARM-программе без покрытия, ему нужна оболочка из libgcc. Нет проблем, я могу связать это. Когда я это делаю, компоновщик перестает жаловаться, но тогда программа зависает (если я наблюдаю, как реестры, на самом деле, начинают крутиться по необъяснимым образом) при использовании мод. Комментируя строку с помощью%, программа не зависает таким образом, так что это определенно проблема.Bare-metal mod (%) зависает на ARMv6 с libgcc

Я построил тривиальный пример задачи на https://gist.github.com/1724746

Я запустить тест с помощью:

qemu-system-arm -M versatilepb -cpu arm1176 -nographic -kernel kernel.elf | xxd 

Тогда^ах выйти из него, и с% линии закомментирована я получаю байты Я ожидаю выхода, но с этой линией я не получаю такого вывода.

Любая идея, что здесь происходит?

Изменить: кросс-компилятор, я использую по умолчанию в Ubuntu на: https://launchpad.net/gcc-linaro

+0

10 вам нужно изучить разборку, можете ли вы разместить соответствующую разборку для созданная вами программа? Вы запускаете это на реальном оборудовании, а не на qemu? –

+0

Я опубликовал мой разобранный код на https://singpolyma.net/test.asm (предупреждение: очень большое!). У меня нет хорошего доступа к какому-либо реальному оборудованию. Моя цель - QEMU. – singpolyma

ответ

2

Так загружает 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 

Интересно, если проблема в режиме большого пальца. У руки1176 определенно есть режим большого пальца, реальный, и я 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 

Вы не можете переключать режимы с ЛДС она должна быть Ьх или BLX, это, вероятно, будет неопределенной проводнику, когда он пытается выполнить большой палец код в ручном режиме.

У меня есть некоторые примеры того, как должны работать режимы переключения, в частности, написанные для qemu.Теперь это пример низкого уровня, например, нет printf, у меня есть выход uart с возможностью увидеть материал на uart. Если это проблема (переход в режим большого пальца), вам нужно изучить, как вы компилируете и связываете свою программу. Возможно, вам нужно будет указать взаимодействие или, возможно, вам нужно будет понять, как была создана ваша инструментальная цепочка, если вы не используете инструментальную цепочку прежнего кода (теперь потребляемую графикой наставника). что предполагается, что вы используете что-то gnu/gcc.

Если у вас есть способ разместить неопределенный обработчик там, или если вы можете следить за трассировкой и видеть падение ПК на что-то около адреса 0x0000000, это, вероятно, то, что происходит. Если вы построите мою маленькую вещь thumb_test, и она использует ldr вместо bx, чтобы попасть туда, то это не должно работать либо оно должно все еще сбой ...

+0

Ссылка на ваш код thumb_test.s и вызов его работы. Добавление -mumb-interwork к CFLAGS не работает. Хм, удаление «.thumb_func» из вашего теста затем вызывает ту же проблему. Таким образом, он не понимает, что этот другой код - большой палец, возможно, каким-то образом. Поэтому мне нужно найти способ убедить компилятор в том, что он звонит в код большого пальца, чтобы создать правильный батут? – singpolyma

+0

Странно, однако, изменение основного кода для компиляции в режиме большого пальца не исправляет его. Устранение несоответствия: http://singpolyma.net/test2.asm – singpolyma

+0

есть много кода thumb2, в котором arm11 не поддерживает thumb2. Если вы удалите по модулю, но скомпилируете эту версию большого пальца, что произойдет? –

Смежные вопросы