我正试图通过此[code] [1]来读取STM32F302C8的硬故障处理程序中的堆栈帧:
__asm volatile
(
" tst lr, #4 n"
" ite eq n"
" mrseq r0, msp n"
" mrsne r0, psp n"
" ldr r1, [r0, #24] n"
" ldr r2, handler2_address_const n"
" bx r2 n"
" handler2_address_const: .word prvGetRegistersFromStack n"
);
但是,生成的汇编指令没有将正确的prvGetReigsetersFromStack
值加载到R2
中。
版本1 :
08000b22 <HardFault_Handler>:
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
SHARED_HARD_FAULT_HANDLER_ASSEMBLY
8000b22: f01e 0f04 tst.w lr, #4
8000b26: bf0c ite eq
8000b28: f3ef 8008 mrseq r0, MSP
8000b2c: f3ef 8009 mrsne r0, PSP
8000b30: 6981 ldr r1, [r0, #24]
8000b32: 4a00 ldr r2, [pc, #0] ; (8000b34 <HardFault_Handler+0x12>)
8000b34: 4710 bx r2
08000b36 <handler2_address_const>:
8000b36: 08006c15 stmdaeq r0, {r0, r2, r4, sl, fp, sp, lr}
}
请注意评论(8000b34 <HardFault_Handler+0x12>)
,我将8000b34
的值而不是8000b36
(即handler2_address_const
)的值加载到r2
更有趣的是,如果我将函数定义移到同一源文件中的某个位置,则代码现在将按预期方式运行:
版本2 :
08000b58 <HardFault_Handler>:
void HardFault_Handler(void)
{
8000b58: b480 push {r7}
8000b5a: af00 add r7, sp, #0
__asm volatile(
8000b5c: f01e 0f04 tst.w lr, #4
8000b60: bf0c ite eq
8000b62: f3ef 8008 mrseq r0, MSP
8000b66: f3ef 8009 mrsne r0, PSP
8000b6a: 6981 ldr r1, [r0, #24]
8000b6c: 4a00 ldr r2, [pc, #0] ; (8000b70 <handler2_address_const>)
8000b6e: 4710 bx r2
08000b70 <handler2_address_const>:
8000b70: 08006c25 stmdaeq r0, {r0, r2, r5, sl, fp, sp, lr}
" bx r2 \n"
" handler2_address_const: .word prvGetRegistersFromStack \n");
}
请注意,注释现在为(8000b70 <handler2_address_const>)
,它是包含指向`prvGetRegistersFromStack的函数指针的内存地址。
请注意,在两个版本的代码中,生成的指令都是相同的: ldr r2,[pc,#0]
, but the comment is different. I thought maybe this was just a mistake by the disassembler, but with **Version 1** of my code, `prvGetRegistersFromStack` never gets called.
I am using the newest `arm-none-eabi-gcc-2019q3-update`.
[1]: https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html
答案 0 :(得分:1)
更新:根本原因是由于对齐。我找到了两种可能的解决方案:
bx
替换为b
,然后直接跳转到该函数HardFault_Handler()
上对齐