ARM汇编的一些常识

来源:互联网 发布:淘宝怎样追加二次评论 编辑:程序博客网 时间:2024/06/05 02:35

常用ARM指令

       1. 数据传传输指令
         mov   例:mov r1 r2  @两个寄存器数据之间的传递
   mvn   与mov的区别是:mov是原封不动的将数据传输,而mvn是将数据按位取反后再传递

       2. 算术指令
           add sub rsb adc sbc rsc

       3. 逻辑指令
           and orr eor bic 

       4. 比较指令
     cmp cmn tst tep
      比较指令的特殊性:比较指令不用添加S后缀就可以影响CPSR的标志位。

       5. 乘法指令
     mvl mla nmull umlal smull smlal

       6. 前导零计数
     clz

       7. CPSR访问指令   (CPSR比较特殊,需要专门指令来访问)
     mrs / msr       mrs用来读cpsr,msr用来写
      CPSR和SPSR两个寄存器的区别与联系:    CPSR是程序状态寄存器,整个SOC上只有1个,而SPSR有5个,分别在5种异常模式下,作用是当从普通模式进入异常模式
              时,用来保存之前普通模式下的CPSR,以在返回普通模式下恢复CPSR。
 
       8. 跳转指令
    b bl bx
b:直接跳转(不用保存返回地址)
bl: 跳转前把返回地址放入到lr中,以便返回,用于函数调用
bx:跳转同时切换到ARM模式,一般用于异常处理跳转
 
       9. 访问内存指令
    ldr/str  ldm/stm  swp
ldr/str: 字节、半字、字的访问
                 ldr:该指令将内存的内容加载到通用寄存器。
                 str:该指令将寄存器的内容存入到内存空间。
ldm/stm:多字批量访问
swp  r1, r2, [r0]  寄存器和内存交换内容
swp  r1, r1, [r0]  @将r0存的内容送给前面r1寄存器,再将后面r1寄存器的内容传给内存r0

   ARM汇编的立即数:合法立即数和非法立即数
ARM指令本身是32位的,除了指令标志和操作标志外,本身只能带很少位数的立即数。
合法立即数:经任意位数的移位后非零部分可以用8位表示。

 10. 软中断指令
     swi 主要用来实现操作系统的系统调用。

!的作用:
        例:ldmia  r0!, {r2 - r3}
        感叹号的作用就是将r0的值在ldm过程中的增加或者减少最后写到r0中去,也就是ldm过程中会改变r0的值。

^的作用:
        例: ldmfd  sp!,{r0-r6,pc}^ 
^的作用:在目标寄存器中有pc时,会同时将SPSR写入CPSR,一般用于从异常处理模式返回。

GNU汇编的一些符号

    1. @  用来做注释
    2. #  用来注释
    3. : 以冒号结尾的是标号,表地址
    4. .  表示当前指令的地址       @汇编循坏 b .
    5. #  立即数面前要加#和$ 
 

GNU常用的伪指令

    1. .global_start     @给_start外部链接属性
    2. .section  .text   @指定当前断为代码段
    3. .ascii  .byte  .short .long .word  .quad(双字)  .float  .string    @定义数据
 汇编数据定义举例:
     IRQ_START:
  .word   0xcaffffff
 等价于C语言
   unsigned int IRQ_SRART = 0xcaffffff;
     4. .align 4   @以16字节对其    2^4 = 16
     5. .balignl  16  0xabcfdcac   @以16字节对其填充,填充内容为 0xabcfdcac   
  b: 表示位填充;  align 表示要对齐;  l 表示long,以4字节为单位填充;  16 表示16字节对齐      
    6. .equ    @相当于C的宏定义 
    7. .end    @标识文件结束
    8. .include  @头文件包含
    9. .arm / .code32    @声明以下为ARM指令
   10. .thumb / .code16   @声明以下为thumb指令


GNU重要的几个伪指令

    1. ldr   大范围的地址加载指令
    2. adr   小范围的地址加载指令
    3. adrl  中等范围的地址加载指令
    4. nop   空操作
       ARM中一般有一个ldr指令和一个ldr伪指令,为了避免数据的合法性,常用ldr伪指令。
 
       adr总是以PC为基准来表示地址,指令本身和地址有关,可以用来检测程序当前运行地址在哪个地方。
       ldr加载的地址和连接时给定的地址有关,由连接脚本决定。


8种寻址方式

       1. 寄存器寻址  例:mov r1,r2    ;将r2的内容赋给r1
       2. 立即寻址    例:mov r0,#0x0f  ;'#'表示后面是一个数,本指令的意思是将0x0f赋给r1
       3. 寄存器移位寻址 例:mov r0, r1,lsl#3  ;将r1左移3位后赋给r1
       4. 寄存器间接寻址 例:ldr r1, [r2]  ;把r2的内存地址赋给r1
       5. 基址变址寻址   例:ldr r1,[r2, #4]  ;把r2地址加4再赋给r1
       6. 多寄存器寻址   例:ldmia r1! , {r2-r7,r12} ;以r1地址为基地址,和以后的地址依次存到r2-r7和r12中  r1可以看作是一个数组的首地址
       7. 堆栈寻址       例:sdmst fp! , {r1-r7,lr}
                      ;用意跟ldmia一样,只是此时是将堆栈里的地址依次放入r1-r7,lr
       8. 相对寻址       例:bep flag flag: ;标号表示入口地址(如函数)

原创粉丝点击