ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
19 мая
61050
Abo (20.06.2006 18:17, просмотров: 3340)
То ли GCC 4.0 зажигает, то ли я не того вкурил? Обясните, знающие. Работаю на CW 1.6 3 билда. Пишу функцию обработки прерывания: <pre> void UsbIsr(void) __attribute__((interrupt("IRQ"))); void UsbIsr(void){ UsbChip.IsrHandler(); VICVectAddr = 0; } </pre> Если в опциях не указывать оптимизацию то данная функция транслируется вот в это: <pre> void UsbIsr(void){ E52DC004 str r12, [sp, #-0x004]! E1A0C00D mov r12, sp E92DD80F stmfd sp!, {r0-r3, r11-r12, lr-pc} E24CB004 sub r11, r12, #0x00000004 UsbChip.IsrHandler(); E59F0020 ldr r0, [pc, #+0x020] EB00057B bl 0x0000347c <TLpc2148UsbController::IsrHandler()> VICVectAddr = 0; E3A03000 mov r3, #0x00000000 E2433EFD sub r3, r3, #0x03f40000 E3A02000 mov r2, #0x00000000 E5832000 str r2, [r3] } E24BD01C sub sp, r11, #0x0000001c E89D680F ldmfd sp, {r0-r3, r11, sp-lr} E8BD1000 ldmfd sp!, {r12} E25EF004 subs pc, lr, #0x00000004 </pre> А если попросить пооптимизировать хотябы Level1 то получается вот что: <pre> void UsbIsr(void) __attribute__((interrupt("IRQ"))); void UsbIsr(void){ E24EE004 sub lr, lr, #0x00000004 E92D500F stmfd sp!, {r0-r3, r12, lr} UsbChip.IsrHandler(); E59F0014 ldr r0, [pc, #+0x014] EB00028C bl 0x00001ad4 VICVectAddr = 0; E3A02000 mov r2, #0x00000000 E3E03000 mvn r3, #0x00000000 E5032FCF str r2, [r3, #-0xfcf] } E8BD500F ldmfd sp!, {r0-r3, r12, lr} E25EF004 subs pc, lr, #0x00000004 </pre> Обратите внимание на самую первую и последнюю команду. Получается что смещение из lr два раза вычитается и возврат из прерывания происходит на команду, которая была выполнена перед вызовом обработчика прерывания. То есть команда выполнится 2 раза. И опыт это подтверждает. Простенькая программка, которая в фоновой функции мыргает светодиодом во время енумерации (производит обращения к памяти и устройствам) отваливаеься в data_abort, если включить оптимизацию. Если оптимизацию выключить - нормально работает. Если же фоновую программу заменить простым while(1); - работает в обоих случаях. Подскажите, знающие, может я чего не так понимаю. Или действительно GCC ЖЖОТ.