• ARM汇编指令


    转载:http://blog.csdn.net/horizontalview/article/details/50773740

    1.mov的用法

    在ARM体系中,mov只能用于数据在寄存器之间的移动或者往寄存器中写入立即数。

    格式如下:mov{条件}{s} 目的寄存器,源操作数

    mov R1,R2;

    2.ldr的用法

    LDR是将内存中的数载入到寄存器,LDR可以载入立即数。

    格式如下:LDR 目的寄存器,源

    LDR     R1,=0xE0000000  ;R1=0xE0000000
    LDR     R1,0xE0000000   ;将内存中地址为0xE0000000的内容载入到R1
    LDR     R1,[R0]         ;将R0中的数所指定的地址的内容传输到R1

    3.str的用法

    STR是将寄存器中的数字载入内存。

    格式如下:STR{条件} 源寄存器,<存储器地址>

    STR     R1,[R0]     ;将R1中的内容传输到R0中的数所指定的地址的内存中去

    三者区别:

    mov 只能用于寄存器之间的传输,传输立即数时有条件限制,只能装载通过偶数次移位能得到的立即数。 
    str/ldr 可以用于寄存器与内存之间的数据交换,STR是将寄存器中的数载入内存,LDR是将内存中的数载入到寄存器,LDR可以载入立即数。 
    并且LDR在往寄存器中载入立即数时,不受立即数的限制,而mov受其限制。

    ARM常用伪指令

    B,BL
    MOV,MVN
    LDR,STR
    ADD,SUB,ADC,SBC,MUL
    AND,ORR,XOR,TST,BIC
    CMP
    LDM/STM
    NOP

    1.跳转语句B,BL:

     程序流程的跳转,在 ARM 程序中有两种方法可以实现程序流程的跳转指令用于实现

    使用专门的跳转指令 B

    直接向程序计数器PC 写入跳转地址值

    这是几乎是任何一种CPU必备的机器,PC表示CPU当前执行语句位置,改变PC的值,相当于实现程序跳转

    如实现类似C语言的Return 语句,就是用MOV PC,LR

    这里可以在任意4G的空间进行跳转

    B(Branch)指令表示无条件跳转。

    B main;//跳转到标号为main地址代码处

    BL指令(Branch with Link),带有返回值的跳转

    BL比B多做一步,在跳转前,BL会把当前位置保存在R14(即LR寄存器),当跳转代码结束后,用MOV PC,LR指令跳回来,这实际上就是C语言执行函数的用法,

       汇编里调子程序都用BL,执行完子函数后,可以用MOV PC,LR跳回来.

       BL delay ;执行子函数或代码段delay ,delay可以为C函数.

    注意:与Mov PC,XXX能在4G空间跳转不同,B语句只能在32M空间跳转(因为偏移量是一个有符号26bit的数值=32M)

    2.传输数据指令MOV,MVN

    MOV(MOVE)指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器

    MOV R0,R1 ; 把R1的值传到R0

    MOV R3,#3 ;把常数3传给R3,MOV中用#表示常数,这个值不能超过

    MVN( MOVE Negative)取反后再传值,比MOV多了一步取反

    MVN R0, #0 ;把0取反(即-1)传给R0

    MVN R1,R2  ;把R2的值取反传给R1

    3.加载/存储指令LDR,STR

     LDR,STR是用于寄存器和外部存储器交换数据指令,注意与MOV的区别,后面只在寄存器或常数交换.

     LDR/STR可以采用多种寻址方式,以下只举出使用频率最高几种用法

    LDR(load)用于把一个32Bit的WORD数据从外部存储空间装入到寄存器中

    LDR R0,[R1]; R1的值当成地址,再从这个地址装入数据到R0 (R0=*R1)

    LDR R1,=0x30008000 ; 把地址0x30008000的值装入到R1中,LDR中用常数要用=打头.(注意跟MOV的区别,MOV是#)

    ldr  r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)

    用位与的方法赋值

    STR(Store) 用于把一个寄存器的值存入外部存储空间,是LDR的逆操作.

    STR R0,[R1] ; 把R0的值,存入到R1对应地址空间上(*R1 = R0)

    STR R0,=0x30008000 ;把R0中值存入到地址0x30008000

    S2C2440的中CPU内核以外的模块的控制寄存器空间也是属于外部空间,所以也得用如下指令LDR R0,=GPFDAT

    4.算术运算指令,ADD/ADC SUB/SBC MUL

     ADD加法指令

    ADD R0,R1,R2; R0=R1+R2

    ADD R0,R1,#3 ;R0=R1+3

    ADC带进位加法指令,即除了加两个数以外,还要把CPSR的C值也要带进来

    通常用于大数(超过32Bit整数)相加,这时单用ADD不能处理,必须折成两步,其中一步用ADC.

    以下是做64Bit的加法

    ADDS R0,R1,R2; R0=R1+R2,ADDS中S表示把进位结果写入CPSR

    ADC R5,R3,R4 ;R5=R3+R4+C

    SUB减法指令

    SUB R0,R1,R2; R0=R1-R2

    SUB R0,R1,#3 ;R0=R1-3

    SBC带进位减法指令,即除了加两个数以外,还要把CPSR的C值也要带进来,类似ADC

     以下是做64Bit的减法

    SUBS R0,R1,R2; R0=R1-R2,SUBS中S表示把进位结果写入CPSR

    SBC R5,R3,R4 ;R5=R3-R4-C

     MUL 乘法指令

    MUL R0,R1,R2; R0=R1*R2

    MUL R0,R1,#3 ;R0=R1*3

    5.位操作指令AND,ORR,TST,BIC

    AND位与指令

    AND R0,R1,R2; R0=R1 & R2

    AND R0,R1,#0xFF ;R0=R1 & 0xFF

    ORR位或指令

    ORR R0,R1,R2; R0=R1 | R2

    ORR R0,R1,#0xFF ;R0=R1 | 0xFF

    TST测试某一位是否为1,并把结果写入CPSR,供下一句使用

    TST R1,#0xffe;   等同于if(R1 & 0xffe)

    TST R1,#%1;测试最低位是否为1,%表示二进制

    BIC清位操作

    BIC   R0,R0,#0xF          ; 等同于 R0 &=~(0xF)

    BIC   R0,R0,#%1011   ; 该指令清除 R0 中的位 0 1  3,其余的位保持;   %表示是二进制,0x表示十六进制

    6.比较指令CMP

    CMP比较两个操作数,并把结果存入CPSR供下一句语句使用

    CMP R0,R1; 比较R0,R1

    7.多寄存器语句传输指令LDM,STM

    类似于一次传一个BUFFER到寄存器当中,或反过来.后面一般要接一个地址改变方法

    LDM 从BUFFER传数据到多个寄存器

    LDMIA R0! ,{R3-R9} ;加R0指向的地址上连续空间的数据,保存到R3-R9当中,!表示R0值更新,IA后缀表示按WORD递增

    LDMFD SP!,{R0-R7,PC}^;恢复现场,异常处理返回,^表示不允许在用户模式下使用。

    STM 从寄存器列表向存储空间传值。

    STMIA R1!,{R3-R9} ;将R3-R9的数据存储到R1指向的地址上,R1值更新。

    STMFD SP!,{R0-R7,LR}; 现场保存,将R0~R7,LR入栈

      stmfd    sp!,{r8-r9} ,把SP寄存器对应的地址的值存到R8,R9当中.!表示最后的值写入SP中。

    8.ARM指令的变形

    大部分指令后位可以接 <cond>与S两个特殊位来表示,对CPSR特殊的一些判断

    S,表示当前指令执行后把结果改写CPSR

    subs,Adds

    <Cond>取决于具体条件,只有CPSR满足指定条件时才指这一指令。

     bne: 数据跳转指令,标志寄存器中Z标志位不等于零时, 跳转到BNE后标签处

     beq: 数据跳转指令,标志寄存器中Z标志位等于零时, 跳转到BEQ后标签处

  • 相关阅读:
    js 数组去重求和 (转载)
    表格插件汇总(转载)
    SQL Server 用一张表的数据更新另一张表的数据(转载)
    C#创建DataTable(转载)
    C# DataTable 和List之间相互转换的方法(转载)
    维度表,实体表,事实表之间的关系
    Scala中foldLeft的总结
    Scala集合Map
    从合并两个Map说开去
    UDAF(用户自定义聚合函数)求众数
  • 原文地址:https://www.cnblogs.com/Caden-liu8888/p/7608088.html
Copyright © 2020-2023  润新知