Есть такой код для Cortex-M3, компилятор CodeSourcery G++ Lite.
CODE
extern "C" void SysTick_Handler()
{
a++;
}
int main()
{
if(SysTick_Config(1000))
{
while(1)
{
}
}
while (1)
{
}
//return 0;
}
{
a++;
}
int main()
{
if(SysTick_Config(1000))
{
while(1)
{
}
}
while (1)
{
}
//return 0;
}
Скомпилил, ассемблерный код обработчика SysTick_Handler выглядит так:
CODE
22 {
SysTick_Handler():
080002d8: push {r7}
080002da: add r7, sp, #0
23 a++;
080002dc: ldr r3, [pc, #16] ; (0x80002f0 <SysTick_Handler()+24>)
080002de: ldr r3, [r3, #0]
080002e0: add.w r2, r3, #1
080002e4: ldr r3, [pc, #8] ; (0x80002f0 <SysTick_Handler()+24>)
080002e6: str r2, [r3, #0]
24 }
080002e8: mov sp, r7
080002ea: pop {r7}
080002ec: bx lr
080002ee: nop
080002f0: movs r4, r5
080002f2: movs r0, #0
SysTick_Handler():
080002d8: push {r7}
080002da: add r7, sp, #0
23 a++;
080002dc: ldr r3, [pc, #16] ; (0x80002f0 <SysTick_Handler()+24>)
080002de: ldr r3, [r3, #0]
080002e0: add.w r2, r3, #1
080002e4: ldr r3, [pc, #8] ; (0x80002f0 <SysTick_Handler()+24>)
080002e6: str r2, [r3, #0]
24 }
080002e8: mov sp, r7
080002ea: pop {r7}
080002ec: bx lr
080002ee: nop
080002f0: movs r4, r5
080002f2: movs r0, #0
Получается, что из-за выделенных кусков нельзя изменять r7, компилер его нигде не использует, но при выходе из прерывания, возвращает в исходное состояние.
Чтобы избавиться от этого сейчас использую вот так определенную функцию:
Код
extern "C" __attribute__((naked)) void SysTick_Handler()
{
a++;
asm volatile("bx lr \n\t");
}
{
a++;
asm volatile("bx lr \n\t");
}
Но не знаю насколько это правильно.
Очень интересно узнать зачем компилятор сохраняет указатель стека в регистр r7, и как это отключить?