嵌入式系统设计与实践:Linux篇
上QQ阅读APP看书,第一时间看更新

3.3 常用ARM指令

3.3.1 内存访问指令

1.基本指令

ldr:存储器memory中数据传送到寄存器register

str:寄存器register中数据传送到存储器memory

例如:

      ldr  r0, [r1]           ;  r1作为指针,该指针指向的数存入r0
      str  r0, [r1, #4]      ;  r1+4作为指针,r0的值存入该地址
      str  r0, [r1, #4]!   ;  同上,并且r1 = r1 + 4
      ldr  r1, =0x08100000   ; 立即数0x08100000存到r1
      ldr  r1, [r2],  #4      ; r2+4作为指针,指向的值存入r1,并且r2=r2+4

2.多字节存取指令

多字节存取指令常应用于堆栈操作。

ldm:存储器memory中数据传送到多个寄存器

stm:多个寄存器中的数据传送到存储器memory

例如:

      sub  lr,lr, #4    ;lr-4是异常处理完后应该返回的地方
      stmfd   sp! , {r0-r12, lr};保存r0~r12和lr寄存器的值到堆栈并更新堆栈指针。
      ldmfd   sp! , {r0-r12, pc}^  ;从堆栈中恢复r0~r12,返回地址赋给pc指针,使程序返回
  到异常发生前所执行的地方,^标记用来使CPU退出异常模式,进入普通状态。

3.3.2 算术运算指令

基本指令:

add:加法指令

sub:减法指令

例如:

    add  r0,r1, r2          ; r0 = r1 + r2
    adds r0,r1, #0x80       ; r0 = r1 + 0x80,并设置状态寄存器
    subs r0,r1, #2000        ; r0 = r1-2000,并设置状态寄存器

3.3.3 逻辑运算指令

基本指令:

and:与指令

orr:或指令

eor:异或

bic:位清0

例如:

      ands r0, r1, #0xff00         ; r0 = r1 and 0xff00,并设置状态寄存器
      orr  r0,r1, r2              ; r0 = r1 and r2
      bics r0,r1, #0xff00         ; r0 = r1 and ! (0xff00),高8位清零

3.3.4 mov指令

例如:

      mov  r0, #8 ; r0 = 8
      mov  r0,r1  ; r0 = r1

mov不同于LDR、STR指令,mov指令可以在寄存器间赋值,LDR用于把内存中数据装载到寄存器,而STR用于把寄存器中的数据装载到内存中。

3.3.5 比较指令

基本指令:

cmp:比较两个操作数,并设置状态寄存器

例如:

      cmp  r0,r1 ;计算r0- r1,并设置状态寄存器,判断r0是否大于、小于或等于r1
      cmp  r0,#0  ;

3.3.6 跳转指令

基本指令:

b:跳转

bl:跳转并将下一指令的地址存入lr寄存器

例如:

      loop1
      …
      b    loop1           ; 跳到地址loop1处
      bl   sub1            ; 将下一指令地址写入lr,并跳至sub1

        …
        sub1
        …
        mov  pc ,   lr          ; 从sub1中返回,保存pc指针的是通用寄存器r15,连接寄存器
    r14(lr)执行有返回的跳转指令bl时,系统将PC保存到r14中。

3.3.7 条件执行指令

条件:状态寄存器中某一或某几个比特的值代表条件,对应不同的条件后缀cond。

例如:

      ;跳转代码
      cmp  r0, r1    ;比较r0和r1
      blgt sub1      ;如果r0>r1,跳转到sub1,否则不操作

在这段程序代码中,通过指令cmp比较r0与r1寄存器的值,如果r0>r1,跳转到sub1,否则不操作。

例如:

      ;一段循环代码
      ldr  r2, =8      ; r2 = 8
      loop
      ;这里可以进行一些循环内的操作
      subs     r2,     r2,     #1      ; r2 = r2-1,并设置状态位
      bne      loop                   ;如果r2不等于0,则继续循环

在这段程序代码中,通过指令cmp比较与寄存器r2是否为0,如果r2不等于0,则跳转到loop继续循环。

      mov      r0,     #1              ; r0 = 1
      cmp      r2,     #8             ;比较r2和8
  movlt   r0,     #2             ;如果r2<8, r0 = 2

在这段程序代码中,通过指令cmp对r2的值与8比较,指令movlt中表明如果r2<8,则把值2赋给r0。