你敲码像蔡徐坤 2023-07-29 22:06 采纳率: 100%
浏览 8
已结题

关于i.mx6ull中断向量表执行问题

i.mx6ull中断向量表部分代码如下:
疑问:在_start中,汇编代码具体是如何执行和跳转的(越具体越好,从下面的代码分析)?ldr pc, =label是否会被执行?
我的理解:
①程序必然执行第一行ldr pc, =Reset_Handler,随后跳转到Reset_Handler中,并最终通过b main跳转到main函数
②剩余的ldr pc,=label 不会被执行,但编译器会给到这些指令相应的程序地址(0x04、0x08、0x0C),用于发生中断时跳转到相应的程序地址去执行中断函数

.global _start

_start:
    ldr     pc, =Reset_Handler           /* Reset                  */     
    ldr     pc, =Undefined_Handler       /* Undefined instructions */
    ldr     pc, =SVC_Handler             /* Supervisor Call        */
    ldr     pc, =PrefAbort_Handler       /* Prefetch abort         */
    ldr     pc, =DataAbort_Handler       /* Data abort             */
    .word   0                                      /* RESERVED               */
    ldr     pc, =IRQ_Handler             /* IRQ interrupt          */
    ldr     pc, =FIQ_Handler             /* FIQ interrupt          */

Reset_Handler:

    cpsid   i                         /* 全局关闭中断 */

    mrc     p15, 0, r0, c1, c0, 0     /*读取CP15系统控制寄存器   */
    bic     r0,  r0, #(0x1 << 12)     /*  清除第12位(I位)禁用 I Cache  */
    bic     r0,  r0, #(0x1 <<  2)     /*  清除第 2位(C位)禁用 D Cache  */
    bic     r0,  r0, #0x2             /*  清除第 1位(A位)禁止严格对齐   */
    bic     r0,  r0, #(0x1 << 11)     /*  清除第11位(Z位)分支预测   */
    bic     r0,  r0, #0x1             /*  清除第 0位(M位)禁用 MMU   */
    mcr     p15, 0, r0, c1, c0, 0     /*  将修改后的值写回CP15寄存器   */

    /* 定义IRQ工作模式的栈起始地址 */
    cps     #0x12                
    ldr     sp, =IRQ_model_stack_start    

    /*定义User工作模式的栈起始地址,与Supervisor相同*/
    cps     #0x1F               
    ldr     sp, =SUP_model_stack_start    

    /*定义Supervisor工作模式的栈起始地址,与User相同 */
    cps     #0x13                
    ldr     sp, =SUP_model_stack_start   

    /*跳转到系统初始化函数,初始化GIC、CACHE-L1、mmu等等*/
    ldr     r2, =SystemInit      
    blx     r2  
   
    /*开启全局中断*/
    cpsie   i                   
  
    /*跳转到到 main 函数执行,*/
    b main                
    b .        /*死循环*/
  • 写回答

3条回答 默认 最新

  • uwen1314 2023-07-30 16:10
    关注

    在i.mx6ull中断向量表部分的代码中,_start标签表示程序的入口点。程序开始执行时,它会首先执行ldr pc, =Reset_Handler这一指令,该指令将Reset_Handler的地址加载到寄存器pc中,并通过跳转指令实现跳转到该地址处执行中断处理函数。然后,程序会进入中断向量表,寻找相应的处理函数,具体如下:

    • 如果发生未定义的指令,程序会跳转到Undefined_Handler处理函数。
    • 如果发生SVC类型的中断,程序会跳转到SVC_Handler处理函数。
    • 如果发生Prefetch Abort异常,程序会跳转到PrefAbort_Handler处理函数。
    • 如果发生Data Abort异常,程序会跳转到DataAbort_Handler处理函数。
    • 如果发生IRQ类型的中断,程序会跳转到IRQ_Handler处理函数。
    • 如果发生FIQ类型的中断,程序会跳转到FIQ_Handler处理函数。

    Reset_Handler中,程序首先关闭全局中断,然后使用MRC指令读取CP15系统控制寄存器中的值。接下来的一系列BIC指令用于清除寄存器中的特定位,用于关闭I Cache、D Cache、严格对齐、分支预测、MMU等功能。之后,程序通过MCR指令将修改后的值写回CP15寄存器。此外,程序还会定义栈的起始地址,然后跳转到系统初始化函数(SystemInit)进行系统初始化。最后,开启全局中断并通过跳转指令跳转到main函数执行。

    对于剩余的ldr pc, =label指令,它们不会被实际执行。这些指令只是用于为中断处理函数指定相应的程序地址,以便在发生中断时跳转到正确的处理函数。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 8月7日
  • 已采纳回答 7月30日
  • 赞助了问题酬金15元 7月30日
  • 创建了问题 7月29日

悬赏问题

  • ¥15 表达式必须是可修改的左值
  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊
  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题