STM32F中断的返回地址

Return Address from Interrupt in STM32F

提问人:MarooNarae 提问时间:11/6/2023 更新时间:11/7/2023 访问量:33

问:

我想知道STM32F中Interrupt的返回地址,尤其是arm处理器。

在正常功能中,返回地址保存在链路寄存器中,但在中断中,我发现链路寄存器的值为0xFFFFFF9。

所以我找到了armv6的参考手册,但我仍然不知道返回地址保存在哪里。

在此处输入图像描述 在此处输入图像描述

我附上了参考手册的一部分。

我猜 ReturnAddress(ExceptionType);是保存退货地址的位置。

所以我检查了 [SP, #24],但值不是返回地址。

ARM 中断 STM32F4Discovery

评论

1赞 jasonharper 11/6/2023
LR 中的0xFFFFFF9值是一个幻数,当执行正常返回指令时,它会导致适当的中断返回行为(例如自动将保存的寄存器从堆栈中弹出)。有几个这样的值,具体取决于中断的确切上下文(例如,返回到主代码,而不是返回到被抢占的低优先级中断处理程序)。实际的返回地址在堆栈上 - 看起来没错,也许在您检查该位置之前,堆栈上已经推送了其他东西?[SP,#24]
0赞 old_timer 11/7/2023
这是前一个问题的重复/重复吗?
0赞 old_timer 11/7/2023
0xFFF....number 是退货地址,即您使用的退货地址。简单的 bx lr 或 pop lr cortex-m 的设计使您可以简单地使用 abi 兼容的编译器编译处理程序,并且它就可以工作了。与其他架构/设计相比,您和编译器都无需付出额外的努力。甚至不需要函数上的 isr 原型,只需程序员知道它是一个处理程序并采取相应的行动(快速进出,没有 printfs 或其他系统调用等)
0赞 old_timer 11/7/2023
请提供一个完整的最小示例,包括堆栈的反汇编和转储。作为创建该示例的一部分,您将自己回答问题,但即使没有,也要发布它。
0赞 old_timer 11/7/2023
Cortex-MS 都不是 ARMv6,它们是 ARMv6-M 或 ARMv7-M 或 ARMv8-M。在这方面,尽管它们都使用相同的 AFAIK。

答:

0赞 old_timer 11/7/2023 #1

这一切都记录在案,您所要做的就是尝试一下。

.thumb_func
.global _start
_start:
stacktop: 
.word 0x20001000
.word reset 
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word svcall
.word hang
.word hang
.word hang
.word hang


.thumb_func
.globl TEST
TEST:
    mov r0,#0
    mov r1,#1
    mov r2,#2
    mov r3,#3
    svc 0
    bx lr

void svcall ( void )
{
...
}

转储堆栈

来自 ARM 文档

MemA[frameptr,4]     = R[0];
MemA[frameptr+0x4,4] = R[1];
MemA[frameptr+0x8,4] = R[2];
MemA[frameptr+0xC,4] = R[3];
MemA[frameptr+0x10,4] = R[12];
MemA[frameptr+0x14,4] = LR;
MemA[frameptr+0x18,4] = ReturnAddress();
MemA[frameptr+0x1C,4] = (xPSR<31:10>:frameptralign:xPSR<8:0>);

编译的 SVCall具有堆栈帧

080001e8 <svcall>:
 80001e8:   b570        push    {r4, r5, r6, lr}

覆盖堆栈的第一部分

00000003 
00000000 
00000000 
FFFFFFF9  lr

然后是逻辑使用的堆栈的异常部分。

00000000 r0
00000001 r1
00000002 r2
00000003 r3
00000000 r12
08000267 lr
0800005E return address
21000000 psr


08000054 <TEST>:
 8000054:   2000        movs    r0, #0
 8000056:   2101        movs    r1, #1
 8000058:   2202        movs    r2, #2
 800005a:   2303        movs    r3, #3
 800005c:   df00        svc 0
 800005e:   4770        bx  lr

这就是预期的返回地址。

不知道为什么你会关心退货地址是什么。请注意,这不是您要分支或返回的地址(如文档所示),当然,在这种情况下,它将是 800005f。但是,如果要返回到该地址,还必须手动恢复寄存器(r0,1,2,...)。