上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。