0

我正在使用 Keil ARMCompiler 6.15 (armclang.exe),我怀疑生成的汇编代码的正确性。在我看来,属性 'interrupt("IRQ")' 被忽略了。对我来说,r1 和 r2 也应该保存在堆栈中。当我删除“使用”属性时,我的完整功能被删除(优化)。

谁能看到我犯的错误或我忘记了什么?

最初代码是为 gcc 创建的。

用于中断例程的属性:

#define INTERRUPT_PROCEDURE __attribute__((interrupt("IRQ"),used,section(".IsrSection")))
#define ISR_VARIABLE __attribute__((section(".IsrSection")))
#define FAST_SHARED_DATA __attribute__((section(".FastSharedDataSection")))

C++ 代码:

uint64_t volatile FAST_SHARED_DATA systick_value = uint64_t(0);
extern "C" {
    void INTERRUPT_PROCEDURE SysTick_Handler()
    {
        systick_value++;
    }
}

汇编代码:

0x08001280  push {r4, r6, r7, lr} 
0x08001282  add r7, sp, #8 
0x08001284  mov r4, sp 
0x08001286  bfc r4, #0, #3 
0x0800128a  mov sp, r4 
0x0800128c  movw r0, #8192  ; 0x2000 
0x08001290  movt r0, #8192  ; 0x2000 
0x08001294  ldrd r1, r2, [r0] 
0x08001298  adds r1, #1 
0x0800129a  adc.w r2, r2, #0 
0x0800129e  strd r1, r2, [r0] 
0x080012a2  sub.w r4, r7, #8 
0x080012a6  mov sp, r4 
0x080012a8  pop {r4, r6, r7, pc} 
0x080012aa  movs r0, r0 
0x080012ac  movs r0, r0 
0x080012ae  movs r0, r0 
4

1 回答 1

0

您不需要此属性。在极少数情况下,当硬件未将堆栈与 8 字节对齐(STKALGN 位未设置)并且您将使用具有 64 位参数的函数(如 uint64_t)时,需要它。ARM 在进入 ISR 处理程序时会自动将 R0-R3 + 一些其他寄存器保存在堆栈上。如果您使用 FPU,您可能还需要启用 FPU 寄存器堆叠。

于 2021-01-25T12:38:59.340 回答