zoukankan      html  css  js  c++  java
  • 部分ARM汇编指令解读

    一、LDR(Load Register  加载寄存器)将存储器地址所指地址处连续的4个字节(1个字)的数据传送到目的寄存器中(pseudo-instruction loads a register with a 32-bit immediate value or an
    address)。

      例:

    1 /* 将Reset_Handler函数的地址加载到pc寄存器中 */
    2 ldr pc, =Reset_Handler
    3 /* 将Reset_Handler函数的地址加载到r0寄存器中*/
    4 ldr r0, =Reset_Handler

    二、BX(Branch and Exchange 分支和交换)指令跳转到指令中所指定的目标地址,若目标地址的bit[0]为0,则跳转时自动将CPSR中的标志位T复位,即把目标地址的代码解释为ARM代码;若目标地址的bit[0]为1,则跳转时自动将CPSR中的标志位T置位,即把目标地址的代码解释为Thumb代码。

      例:

    1 /* 以下指令的作用是在函数Reset_Handler中一直循环 */
    2 Reset_Handler:
    3   ldr r0, =Reset_Handler
    4   bx r0

    三、MRC读CP15(C0-C15)寄存器

      MRC{cond} p15, <opc1>, <Rt>, <CRn>, <CRm>, <opc2> 

    1. cond:指令执行的条件码,如果忽略的话就表示无条件执行 ;
    2. opc1:协处理器要执行的操作码 ;
    3. RtARM 源寄存器,要写入到 CP15 寄存器的数据就保存在此寄存器中 ;
    4. CRnCP15 协处理器的目标寄存器;
    5. CRm: 协处理器中附加的目标寄存器或者源操作数寄存器,如果不需要附加信息就将;
      CRm 设置为 C0,否则结果不可预测;
    6. opc2: 可选的协处理器特定操作码,当不需要的时候要设置为 0 。

    例:

    MRC p15, 0, r0, c0, c0, 0 ;将 CP15 中 C0 寄存器的值读取到 R0 寄存器中

    四、MCR写CP15(C0-C15)寄存器

      MCR{cond} p15, <opc1>, <Rt>, <CRn>, <CRm>, <opc2> 

      同上。

    例:

    ldr r0, =0X87800000     ; r0=0X87800000 
    MCR p15, 0, r0, c12, c0, 0 ;将 r0 里面的数据写入到 c12 中,即 c12=0X87800000 

    五、 ADD(add 加)不带进位的加法指令,指令完成目的操作数与源操作数相加,将结果存回目标操作数。

    例:

    MRC p15, 4, r1, c15, c0, 0   ;获取 GIC 基地址 
    ADD r1, r1, #0X2000       ;GIC 基地址加 0X2000 得到 CPU 接口端寄存器起始地址 
    LDR r0, [r1, #0XC]        ;读取 CPU 接口端起始地址+0XC 处的寄存器值,也就是寄存器     
                      ;GIC_IAR 的值

     六、CPSID(禁止IRQ中断)和CPSIE(打开IRQ中断)

      Syntax

      CPSIE iflags{, #mode}
      CPSID iflags{, #mode}

      where

      IE Interrupt or Abort Enable.

      ID Interrupt or Abort Disable.

      iflags specifies one or more of:
      • a = asynchronous abort.
      • i = IRQ.
      • f = FIQ. 

    例:

    cpsid i  ;禁止IRQ中断
    cpsie i  ; 打开IRQ中断

     七、BIC(位清除)可以用来清除寄存器的指定位

    例:

    1 mrc p15, 0, r0, c1, c0, 0     /* 读取CP15的C1寄存器到R0中            */
    2 bic r0, r0, #(0x1 << 12)      /* 清除C1寄存器的bit12位(I位),关闭I Cache   */
    3 bic r0, r0, #(0x1 <<  2)      /* 清除C1寄存器的bit2(C位),关闭D Cache     */
    4 bic r0, r0, #0x2              /* 清除C1寄存器的bit1(A位),关闭对齐        */
    5 bic r0, r0, #(0x1 << 11)      /* 清除C1寄存器的bit11(Z位),关闭分支预测    */
    6 bic r0, r0, #0x1              /* 清除C1寄存器的bit0(M位),关闭MMU        */
    7 mcr p15, 0, r0, c1, c0, 0     /* 将r0寄存器中的值写入到CP15的C1寄存器中    */

     八、DSB(数据同步隔离)、ISB(指令同步隔离)和DMB(数据存储器隔离)

      DSB: 仅当所有在它前面的存储器访问操作都执行完毕后,才执行在它后面的指令;

      ISB:它会清洗流水线,以保证所有它前面的指令都执行完毕后,才执行它后面的指令;

      DMB:仅当所有在它前面的存储器访问操作都执行完毕后,才提交(commit)在它后面的存储器访问操作。

     例:

        ldr r0, =0X87800000
        dsb
        isb
        mcr p15, 0, r0, c12, c0, 0      /* 将0x87800000地址写到c12寄存器中 */
        dsb
        isb

     九、MRS(状态寄存器传送至通用寄存器传送指令)和MSR(通用寄存器传送至状态寄存器传送指令)

      MRS:将状态寄存器的内容传送至通用寄存器;

      MSR:将通用寄存器的内容传送至状态寄存器;

    例:

        /* 进入IRQ模式 */
        mrs r0, cpsr                    /* 将cpsr中的内容写到r0寄存器中 */
        bic r0, r0, #0x1F               /* 将r0寄存器中的低5位清零,也就是cpsr的M0-M4 */ 
        orr r0, r0, #0x12               /* r0或上0x12,表示使用IRQ模式 */
        msr cpsr, r0                    /* 将r0的数据写入到cpsr中 */
        ldr sp, =0x80600000             /* 设置SYS模式下的栈首地址为0x80600000 */

    十、PUSH入栈和POP出栈,遵循先进后出原,则即FILO

    例:

     1    push {lr}                    /* 保存lr寄存器 */
     2    push {r0-r3, r12}            /* 保存r0-r3,r12寄存器 */
     3 
     4    mrs r0, spsr                 /* 读spsr寄存器 */
     5    push {r0}                    /* 保存spsr寄存器 */
     6 
     7    mrc p15, 4, r1, c15, c0, 0   /* 将CP15的C0内的值保存到R1寄存器中 */
     8 
     9    add r1, r1, #0x2000          /* GIC基地址加0x2000,得到CPU接口端基地址 */
    10    ldr r0, [r1, #0xC]           /* CPU接口端基地址加0x0C就是GICC_IAR寄存器 */
    11                                 /* GICC_IAR保存着当前发生中断的中断号 */
    12 
    13     push {r0, r1}               /* 保存r0和r1 */
    14 
    15     cps #0x13                   /* 进入SVC模式,允许其他中断再次进去 */
    16 
    17     push {lr}                   /* 保存SVC模式的lr寄存器 */
    18     ldr r2, =system_irqhandler  /* 加载c语言中断处理函数到r2寄存器中 */
    19     blx r2                      /* 运行c语言中断处理函数,带有一个参数 */
    20     pop {lr}                    /* 执行完c语言中断服务函数,lr出栈 */
    21 
    22     cps #0x12                   /* 进入IRQ模式 */
    23 
    24     pop {r0, r1}
    25 
    26     str r0, [r1, #0x10]         /* 中断执行完成,写EOIR */
    27 
    28     pop {r0}
    29     msr spsr_cxsf, r0           /* 恢复spsr */
    30 
    31     pop {r0-r3, r12}            /* r0-r3,r12除栈 */
    32     pop {lr}                    /* lr出栈 */
    33     subs pc, lr, #4             /* 将lr-4赋给pc */

     十一、CPS(Change Processor Status 改变处理器状态)用于改变处理器的状态或者是使能、禁用单独的异常类型(Can be used to change the processor mode or to enable or disable
    individual exception types)。

      Syntax
      CPS #mode
      where:
      mode is the number of a mode for the processor to enter.

    例:

    1 cps #0x12                   /* 进入IRQ模式 */

      

  • 相关阅读:
    WCF Security基本概念(转载)
    Step by Step 配置使用HTTPS的ASP.NET Web应用
    HTTPS那些事(三)攻击实例与防御(转载)
    HTTPS那些事(二)SSL证书(转载)
    HTTPS那些事(一)HTTPS原理(转载)
    WCF服务创建与抛出强类型SOAP Fault
    WCF服务的异常消息
    如何创建一个RESTful WCF Service
    (转)webHttpBinding、basicHttpBinding和wsHttpBinding区别
    如何创建一个AJAX-Enabled WCF Service
  • 原文地址:https://www.cnblogs.com/wenhao-Web/p/12686452.html
Copyright © 2011-2022 走看看