• Linux异常体系之vector_stub宏解析


     ARM-Linux汇编的宏定义语法说明如下:

    使用注意:

    1.宏定义以.macro开始,以.endm结束

    2.可带参数,参数可有默认值

    3.直接使用参数的名字arg

    vector_stub宏的功能:

    计算处理完异常的返回地址;

    保存寄存器(r0,lr,spsr)

    进入管理模式;

    最后根据进入异常前的模式跳转到相应的某个分支。

     1 /*
     2  * Vector stubs.
     3  *
     4  * This code is copied to 0xffff0200 so we can use branches in the
     5  * vectors, rather than ldr's.  Note that this code must not
     6  * exceed 0x300 bytes.
     7  *
     8  * Common stub entry macro:
     9  *   Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
    10  *
    11  * SP points to a minimal amount of processor-private memory, the address
    12  * of which is copied into r0 for the mode specific abort handler.
    13  */
    14     .macro    vector_stub, name, mode, correction=0
    15     .align    5
    16 
    17 vector_
    ame:
    18     .if correction
    19     sub    lr, lr, #correction
    20     .endif
    21 
    22     @
    23     @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
    24     @ (parent CPSR)
    25     @
    26     stmia    sp, {r0, lr}        @ save r0, lr
    27     mrs    lr, spsr
    28     str    lr, [sp, #8]        @ save spsr
    29 
    30     @
    31     @ Prepare for SVC32 mode.  IRQs remain disabled.
    32     @
    33     mrs    r0, cpsr
    34     eor    r0, r0, #(mode ^ SVC_MODE)
    35     msr    spsr_cxsf, r0
    36 
    37     @
    38     @ the branch table must immediately follow this code
    39     @
    40     and    lr, lr, #0x0f
    41     mov    r0, sp
    42     ldr    lr, [pc, lr, lsl #2]
    43     movs    pc, lr            @ branch to handler in SVC mode
    44     .endm

     展开

     1 /*
     2  * Interrupt dispatcher
     3  */
     4     vector_stub    irq, IRQ_MODE, 4
     5 
     6     .long    __irq_usr            @  0  (USR_26 / USR_32)
     7     .long    __irq_invalid            @  1  (FIQ_26 / FIQ_32)
     8     .long    __irq_invalid            @  2  (IRQ_26 / IRQ_32)
     9     .long    __irq_svc            @  3  (SVC_26 / SVC_32)
    10     .long    __irq_invalid            @  4
    11     .long    __irq_invalid            @  5
    12     .long    __irq_invalid            @  6
    13     .long    __irq_invalid            @  7
    14     .long    __irq_invalid            @  8
    15     .long    __irq_invalid            @  9
    16     .long    __irq_invalid            @  a
    17     .long    __irq_invalid            @  b
    18     .long    __irq_invalid            @  c
    19     .long    __irq_invalid            @  d
    20     .long    __irq_invalid            @  e
    21     .long    __irq_invalid            @  f

    后得到

     1 /*
     2  * Interrupt dispatcher
     3  */
     4     .align    5
     5 
     6 vector_irq:
     7     sub    lr, lr, #4               //保存irq返回地址
     8 
     9     @
    10     @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
    11     @ (parent CPSR)
    12     @
    13     stmia    sp, {r0, lr}        @ save r0, lr
    14     mrs    lr, spsr
    15     str    lr, [sp, #8]        @ save spsr
    16 
    17     @
    18     @ Prepare for SVC32 mode.  IRQs remain disabled.
    19     @
    20     mrs    r0, cpsr
    21     eor    r0, r0, #(mode ^ SVC_MODE)
    22     msr    spsr_cxsf, r0 //对spsr的所有控制位进行写操作,将r0的值全部注入spsr,进入svc模式
    23 
    24     @
    25     @ the branch table must immediately follow this code
    26     @
    27     and    lr, lr, #0x0f  //根据进入中断前的模式跳转到相应的中断处理函数
    28     mov    r0, sp
    29     ldr    lr, [pc, lr, lsl #2]
    30     movs    pc, lr            @ branch to handler in SVC mode
    31 
    32 
    33     .long    __irq_usr            @  0  (USR_26 / USR_32)
    34     .long    __irq_invalid            @  1  (FIQ_26 / FIQ_32)
    35     .long    __irq_invalid            @  2  (IRQ_26 / IRQ_32)
    36     .long    __irq_svc            @  3  (SVC_26 / SVC_32)
    37     .long    __irq_invalid            @  4
    38     .long    __irq_invalid            @  5
    39     .long    __irq_invalid            @  6
    40     .long    __irq_invalid            @  7
    41     .long    __irq_invalid            @  8
    42     .long    __irq_invalid            @  9
    43     .long    __irq_invalid            @  a
    44     .long    __irq_invalid            @  b
    45     .long    __irq_invalid            @  c
    46     .long    __irq_invalid            @  d
    47     .long    __irq_invalid            @  e
    48     .long    __irq_invalid            @  f
  • 相关阅读:
    【Anagrams】 cpp
    【Count and Say】cpp
    【Roman To Integer】cpp
    【Integer To Roman】cpp
    【Valid Number】cpp
    重构之 实体与引用 逻辑实体 逻辑存在的形式 可引用逻辑实体 不可引用逻辑实体 散弹式修改
    Maven项目聚合 jar包锁定 依赖传递 私服
    Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器
    mysql案例~tcpdump的使用
    tidb架构~本地化安装
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/7629928.html
Copyright © 2020-2023  润新知