You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TMS320C28x汇编:替换LCR指令实现地址入栈供ExitBoot加载

问题根源

你碰到的启动数据损坏问题,根源是LCR指令执行时会自动把返回地址压进硬件栈,后面ExitBoot流程重置栈指针、初始化栈空间的时候,会把这部分提前压入的残留地址当成栈初始化内容,导致栈数据错位、内存异常。

汇编侧修改方案(替换LCR、无栈污染跳转)

你不需要手动压栈传地址,也别直接用LB _c_int00跳过ExitBoot的标准初始化流程——ExitBoot本身的逻辑就是从ACC寄存器读入口地址,完成栈重置、寄存器清零、状态寄存器恢复后,通过LRETR跳转到入口,全程不会产生多余的栈写入。

  • 修改codestart段的分支逻辑,把直接跳_c_int00的代码替换为「加载入口地址到ACC + 跳转到ExitBoot」:
    code_start:
        .if WD_DISABLE == 1
            LB wd_disable       ;Branch to watchdog disable code
        .else
            ; 删除原有的LB _c_int00指令,替换为以下两行
            MOVL ACC, #_c_int00  ; 把_c_int00的入口地址加载到ACC寄存器
            BF ExitBoot, UNC     ; 无条件跳转到ExitBoot完成初始化
        .endif
    
  • 修改wd_disable段的尾部逻辑,删掉提前跳转_c_int00的指令,让代码走到加载地址、跳ExitBoot的流程:
    wd_disable:
        SETC OBJMODE        ;Set OBJMODE for 28x object code
        EALLOW              ;Enable EALLOW protected register access
        MOVZ DP, #7029h>>6  ;Set data page for WDCR register
        MOV @7029h, #0068h  ;Set WDDIS bit in WDCR to disable WD
        EDIS                ;Disable EALLOW protected register access
        ; 删除原有的LB _c_int00指令,替换为以下两行
        MOVL ACC, #_c_int00  ; 加载入口地址到ACC
        BF ExitBoot, UNC     ; 跳转到ExitBoot
    

这套逻辑和TI官方BootROM的跳转流程完全一致,不会产生多余的栈操作,从根源避免数据损坏。

C函数侧操作:将地址存入ACC寄存器的方法

针对TMS320C28x架构的TI C2000编译器,有两种不需要复杂汇编适配的实现方式:

  • 利用编译器默认调用约定(无额外汇编代码)
    C28x编译器的默认规则是:32位宽度的函数返回值默认存放在ACC寄存器中。你只要定义一个返回void*类型指针的函数,把需要跳转的入口地址作为返回值返回,编译器会自动把地址加载到ACC中,示例:
    // 函数返回32位指针,返回值自动存入ACC
    void* GetBootEntryAddr(void)
    {
        // 可以返回_c_int00、main,也可以返回固定地址的APP入口,比如return (void*)0x300000;
        return (void*)_c_int00;
    }
    
    汇编侧调用这个函数后,不需要额外操作,ACC里已经存好入口地址,直接跳ExitBoot即可。
  • 内联汇编直接赋值(可控性更高)
    如果需要直接在C代码中完成地址加载和跳转,可以用内联汇编直接操作ACC,注意提前声明ExitBoot为外部符号:
    // 声明外部汇编实现的ExitBoot
    extern void ExitBoot(void);
    
    void JumpToEntry(uint32_t entry_addr)
    {
        // 把传入的入口地址直接加载到ACC
        asm("MOVL ACC, @_entry_addr");
        // 直接跳转到ExitBoot完成启动
        asm("BF ExitBoot, UNC");
    }
    

注意:C28x的程序地址为22位宽度,存入ACC时使用低22位、高10位保留为0即可,使用MOVL指令加载地址时,编译器会自动处理地址对齐,不需要手动移位。

内容的提问来源于stack exchange,提问作者HansPeterLoft

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 07:01:02