调试绝招—栈回溯

保存在哪儿     栈

找到汇编里面的  HardFault_Handler 函数,注销原来的代码,添加一下代码


;HardFault_Handler
;                PROC
;                EXPORT  HardFault_Handler          [WEAK]
;                B       .
;                ENDP

    IMPORT rt_hw_hard_fault_exception
    EXPORT HardFault_Handler
HardFault_Handler    PROC

    ; get current context
    TST     lr, #0x04               ; if(!EXC_RETURN[2])
    ITE     EQ
    MRSEQ   r0, msp                 ; [2]=0 ==> Z=1, get fault context from handler.
    MRSNE   r0, psp                 ; [2]=1 ==> Z=0, get fault context from thread.

    STMFD   r0!, {r4 - r11}         ; push r4 - r11 register
    STMFD   r0!, {lr}               ; push exec_return register

    TST     lr, #0x04               ; if(!EXC_RETURN[2])
    ITE     EQ
    MSREQ   msp, r0                 ; [2]=0 ==> Z=1, update stack pointer to MSP.
    MSRNE   psp, r0                 ; [2]=1 ==> Z=0, update stack pointer to PSP.

    PUSH    {lr}
    BL      rt_hw_hard_fault_exception
    POP     {lr}

    ORR     lr, lr, #0x04
    BX      lr
    ENDP

然后在stm32xx_it.c中包覆盖HardFault_Handler这个函数

#if 0
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}
#else

#define rt_uint32_t unsigned int
struct exception_info
{
    rt_uint32_t exc_return;
    rt_uint32_t r4;
    rt_uint32_t r5;
    rt_uint32_t r6;
    rt_uint32_t r7;
    rt_uint32_t r8;
    rt_uint32_t r9;
    rt_uint32_t r10;
    rt_uint32_t r11;
    rt_uint32_t r0;
    rt_uint32_t r1;
    rt_uint32_t r2;
    rt_uint32_t r3;
    rt_uint32_t r12;
    rt_uint32_t lr;
    rt_uint32_t pc;
    rt_uint32_t psr;
};


/*
 * fault exception handler
 */
void rt_hw_hard_fault_exception(struct exception_info * exception_info)
{
    unsigned int *app_sp;

    int i;
    app_sp = (unsigned int *)(exception_info + 1);  /* context + 16*4 */
    
    printf("psr: 0x%08x\r\n", exception_info->psr);
    printf("r00: 0x%08x\r\n", exception_info->r0);
    printf("r01: 0x%08x\r\n", exception_info->r1);
    printf("r02: 0x%08x\r\n", exception_info->r2);
    printf("r03: 0x%08x\r\n", exception_info->r3);
    printf("r04: 0x%08x\r\n", exception_info->r4);
    printf("r05: 0x%08x\r\n", exception_info->r5);
    printf("r06: 0x%08x\r\n", exception_info->r6);
    printf("r07: 0x%08x\r\n", exception_info->r7);
    printf("r08: 0x%08x\r\n", exception_info->r8);
    printf("r09: 0x%08x\r\n", exception_info->r9);
    printf("r10: 0x%08x\r\n", exception_info->r10);
    printf("r11: 0x%08x\r\n", exception_info->r11);
    printf("r12: 0x%08x\r\n", exception_info->r12);
    printf(" lr: 0x%08x\r\n", exception_info->lr);
    printf(" pc: 0x%08x\r\n", exception_info->pc);

    printf("stacks: \r\n");
    i = 0;
    for (i = 0; i < 1024; )
    {
        printf("%08x ", *app_sp);
        app_sp++;
        i++;
        if (i % 16 == 0)
            printf("\r\n");
            
    }
    printf("\r\n");

    while (1);
}

#endif

串口打印找到PC寄存器的地址            查看反汇编

fromelf  --text  -a -c  --output=all.dis    F103_Moduel\F103_Moduel.axf

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来为您解答这个问题。 1)定义一个游戏中Hero 英雄的类,在该类中定义英雄的名字, 生命值和等级3 个属性,定义一个构造函数完成对生命值和等级的初始化,分别赋初值为100,1。同时实现名字的输入和英雄信息的输出。 ``` class Hero: def __init__(self, name): self.name = name self.hp = 100 self.level = 1 def show_info(self): print("英雄名字:", self.name) print("英雄生命值:", self.hp) print("英雄等级:", self.level) ``` 2)在上一题的基础上,为英雄再定义拥有一个参数的构造方法,传入一个英雄类型的值,如果为1,则为普通英雄,生命值为100,如果该值为2,则为高级英雄,生命值初始化为200。 ``` class Hero: def __init__(self, name, hero_type=1): self.name = name if hero_type == 1: self.hp = 100 elif hero_type == 2: self.hp = 200 else: raise ValueError("英雄类型错误") self.level = 1 def show_info(self): print("英雄名字:", self.name) print("英雄生命值:", self.hp) print("英雄等级:", self.level) ``` 3)在上两英雄类型的基础上,为英雄添加一个基本战斗的方法, 该方法拥有一个英雄类型的参数,当传入另一个英雄时,能降低对方100 点血。 再增加一个绝招的重载方法,加入一个战斗类型参数,通过输入不同绝招参数,降低对方不同的血量。 ``` class Hero: def __init__(self, name, hero_type=1): self.name = name if hero_type == 1: self.hp = 100 elif hero_type == 2: self.hp = 200 else: raise ValueError("英雄类型错误") self.level = 1 def show_info(self): print("英雄名字:", self.name) print("英雄生命值:", self.hp) print("英雄等级:", self.level) def attack(self, other_hero): other_hero.hp -= 100 print(self.name, "攻击了", other_hero.name) print(other_hero.name, "受到了100点伤害") def ultimate(self, other_hero, skill_type): if skill_type == "大招1": other_hero.hp -= 200 print(self.name, "使用了大招1攻击了", other_hero.name) print(other_hero.name, "受到了200点伤害") elif skill_type == "大招2": other_hero.hp -= 300 print(self.name, "使用了大招2攻击了", other_hero.name) print(other_hero.name, "受到了300点伤害") else: raise ValueError("绝招类型错误") ``` 以上就是这个题目的解答,希望能够帮到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值