ARM所有常用指令的实例与说明(2)

.LC:
  ldr r0, .LC :表示把.LC所处内存地址里面的4个字节值赋给r0 (这种情况需要此命令与标签在同一段内)
  ldr r0, =.LC :表示直接把.LC所处的地址赋给r0
  ldr r0, [r1] : 表示把把r1所代表的内存地址里面的值赋给r0
  ldr r0, [r1, #8]  : 表示r1加上8个字节代表的内存地址里面的值赋给r0
  ldr r0, [r1, #8]! : 表示r1加上8个字节代表的内存地址里面的值赋给r0, 然后把r1 = r1 + 8
  ldr r0, [r1], #4 : 表示把r1所代表的内存地址里面的值赋给r0, 之后, r1 += 4
  ldr r0, [r1, r2, LSL #2] :表示把r1+r2 * 4所代表的内存地址里面的值赋给r0
 
  str r0, [r1, r2] : 把r1 + r2所代表的内存地址里面的值赋入r0 
  str r0, [r1, r2]! : 把r1 + r2所代表的内存地址里面的值赋入r0, r1 = r1 + r2


ldm, stm指令:
 语法: <ldm/stm><ed|fd|ea|fa> Rn{!}, <Rlist>{^}

Rlist, 表示寄存器列表。比如{r0, r2, r5-r7,r9 }
 {!},  表示执行完ldm或stm之后是否对Rn进行回写。
 {^}, 表示恢复spsr中的值到cpsr。(一般用于返回以前模式)

寄存器列表中的数据在内存中将被存放的顺序为低寄存器对应低内存地址的顺序存放。
 stm操作始终与所指定的栈的方向保持相同,ldm相反。stm就相当于压栈,ldm就相当于退栈。
 
 stm表示把寄存器的数据存入内存
 ldm表示把内存中的数据加载到寄存器上。
 
 例如:
  ldmfd sp, {r0,r1,r2} 表示把sp所指的内存地址开始的12个字节分别赋值给r0,r1,r2。 
  ldmfd sp!, {r0,r1,r2} 表示把sp所指的内存地址开始的12个字节分别赋值给r0,r1,r2,之后sp = sp + 12
  ldmfd sp!, {r15}^ 表示把sp棧所指的4个字节里面的值赋给r15, 同时把spsr赋值给cpsr,并且sp += 4
 
  stmfd sp, {r0, r1, r2} 表示把r2,r1,r0按照sp所指地址递减存储。也就相当于下面3条指令:
   str r2, [sp, #-4]
   str r1, [sp, #-8]
   str r0, [sp, #-12]

stmfd sp!, {r0, r1, r2}  表示把r2,r1,r0按照sp所指地址递减存储。并且把sp = sp - 12,也就相当于下面4条指令:
   str r2, [sp, #-4]
   str r1, [sp, #-8]
   str r0, [sp, #-12]
   sub sp, sp, #12


  特殊用法:

stmfd sp!, {r0-r15}^ : 表示把用户模式下面的r0-r15寄存器存在当前模式下面的sp所指向的栈中。
   stmfd sp!, {r0-r14}^ : 表示把用户模式下面的r0-r14寄存器存在当前模式下面的sp所指向的栈中。用于进程切换的时候保存用户模式下面的寄存器。
   ldmfd sp!, {r0-r14}^ : 寄存器列表这里面不带有r15(pc), 表示把当前模式下面sp所指的栈中的15个int拷贝用户模式下面的r0-r14。这个用于恢复进程状态。
 
 

swp指令: 
 语法: <swp><b/h> Rd, Rm, [rn]

swp指令执行单字节或单字的内存于寄存器的数据交换原子操作。把rn所指内存里面的值赋值给Rd, 然后把R1存入R2所指的内存。经常用于内核中实现控制互斥与信号等功能。

例如:
 
 swp r0, r1,[r2] :表示把r2所指的内存地址里面的值赋值给r0, 然后把r1存入r2所指内存地址。相当于下面2条指令的原子操作。
   ldr r0, [r2]
   str r1, [r2]

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ab0b9fda75821fff145bcd6b7fc74f15.html