ARM 汇编指令

1)汇编特点

1、 通用寄存器(一般是R0~R14),与硬件打交道。
2ARM汇编语句中.当前语句很多时候要隐含的使用上一句的执行结果.而且上一句的执行结果,是放在CPSR寄存器里,(比如说进位,0,为负…)
CMP R0,R1//比较
BNE NoMatch//不相等
比如上一句,BNE隐含的使用的上一句CMP执行结果.NE后缀表示使用Z标志位.两句合起来的意思就是,如果R0,R1的值不相等,就跳转到NoMatch处执行.
注意,PC=R15,CPSR=R16,

2) 常用指令

 B,BL; MOV,MVN;      LDR,STR;     ADD,SUB,ADC,SBC,MUL;         AND,ORR,XOR,TST,BIC;       CMP;         LDM/STM;         nop;
1)跳转指令
在 ARM 程序中有两种方法可以实现程序流程的跳转指令用于实现
l  使用专门的跳转指令 B
l  直接向程序计数器PC 写入跳转地址值
n  这是几乎是任何一种CPU必备的机器,PC表示CPU当前执行语句位置,改变PC的值,相当于实现程序跳转
n  如实现类似C语言的Return 语句,就是用MOV PC,LR
n  这里可以在任意4G的空间进行跳转
 
1、B指令(Branch)表示无条件跳转.
   B main ;跳转到标号为main地代码处
2、BL指令(Branch with Link)表示带返回值的跳转.

 BL比B多做一步,在跳转前,BL会把当前位置保存在R14(即LR寄存器),当跳转代码结束后,用MOV PC,LR指令跳回来,相当于return;
   汇编里调子程序都用BL,执行完子函数后,可以用MOV PC,LR跳回来.

MOV PC,XXX能在4G空间跳转不同,B语句只能32M空间跳转,(因为偏移量是一个有符号26bit的数值=32M)
 
2.)  传输数据指令MOV,MVN
n  MOV(MOVE)指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器
MOV R0,R1 ; 把R1的值传到R0
MOV R3,#3 ;把常数3传给R3,MOV中用#表示常数,这个值不能超过
n  MVN( MOVE Negative)取反后再传值,比MOV多了一步取反
MVN R0, #0 ;把0取反(即-1)传给R0

MVN R1,R2  ;把R2的值取反传给R1
 
3.) 加载/存储指令,LDR,STR
n  LDR,STR是用于寄存器和外部存储器交换数据指令 
n  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)
用位与的方法赋值
 
n  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
n         ADD加法指令
ADD R0,R1,R2; R0=R1+R2
ADD R0,R1,#3 ;R0=R1+3
n         ADC带进位加法指令,即除了加两个数以外,还要把CPSR的C值也要带进来
u              通常用于大数(超过32Bit整数)相加,这时单用ADD不能处理,必须折成两步,其中一步用ADC.
u              以下是做64Bit的加法
ADDS R0,R1,R2; R0=R1+R2,ADDS中S表示把进位结果写入CPSR
ADC R5,R3,R4 ;R5=R3+R4+C
n         SUB减法指令
SUB R0,R1,R2; R0=R1-R2
SUB R0,R1,#3 ;R0=R1-3
n         SBC带进位减法指令,即除了加两个数以外,还要把CPSR的C值也要带进来,类似ADC

u              以下是做64Bit的减法
SUBS R0,R1,R2; R0=R1-R2,SUBS中S表示把进位结果写入CPSR
SBC R5,R3,R4 ;R5=R3-R4-C
n         MUL 乘法指令

MUL R0,R1,R2; R0=R1*R2
MUL R0,R1,#3 ;R0=R1*3
 
5.) 位操作指令 AND,ORR, TST,BIC
n         AND位与指令
AND R0,R1,R2; R0=R1 & R2
AND R0,R1,#0xFF ;R0=R1 & 0xFF
n         ORR位或指令
ORR R0,R1,R2; R0=R1 | R2
ORR R0,R1,#0xFF ;R0=R1 | 0xFF
n         TST测试某一位是否为1,并把结果写入CPSR,供下一句使用
TST R1,#0xffe;   等同于if(R1 & 0xffe)
TST R1,#%1;测试最低位是否为1,%表示二进制
n         BIC清位操作
BIC   R0,R0,#0xF           等同于 R0 &=~(0xF)
BIC   R0,R0,#%1011   ; 该指令清除 R0 中的位 0 1  3,其余的位保持;   %表示是二进制,0x表示十六进制
6.)   比较指令 CMP
n         CMP比较两个操作数,并把结果存入CPSR供下一句语句使用
CMP R0,R1; 比较R0,R1
 

7.)  多寄存器语句传输指令,LDM,STM
类似于一次传一个BUFFER到寄存器当中,或反过来.后面一般要接一个地址改变方法
n         LDM 从BUFFER传数据多个寄存器传输数据到
LDMIA R0! ,{R3-R9} ;R0指向的地址上连续空间的数据,保存到R3-R9当中,!表示R0值更新,IA后缀表示按WORD递增

LDMFD SP!,{R0-R7,PC}^;恢复现场,异常处理返回,^表示不允许在用户模式下使用。
n         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指令的寻址方式
  寻址方式是根据指令中给出的地址码来定位真实的地址,ARM中有9种寻址方法
l  寄存器寻址
直接用寄存器编号来寻址,最为常用
  MOV R1,R2 ;R2->R1
l  立即数寻址
即指令中的地址码是操作数本身,可以立即取出使用,立即数前带一个#表示,否则表示一个地址
SUBS R0,R0,#1   ;R0 -1 ->R0
注意与SUBS R0,R0,1区别
l  寄存器偏移寻址
这是ARM特有的寻址模式,当第2操作数是寄存器,在执行操作之前,可以做一次移位操作
MOV R0,R2,LSL #3 ;R2的逻辑左移3位,结果放入R0,即R0=R2*8
ANDS R1,R1,R2,LSL R3;RS的值左移R3位,然后和R1相与操作,结果放入R1
移位操作有LSL (逻辑左移),LSR(逻辑右移) ,ASR(算术右移),ROR(循环右移)RRX
带扩展的循环右移

l         寄存器间接寻址
即寄存器中值是一个地址,用[]来取出定位到地址当中
 LDR R2,[R0] ;把R0的值当成地址,取出相应值,赋给R2
l         基址寻址
把寄存器的地址值加上一个偏移量
LDR R2,[R3,#0x0F]; R3中的值加上0x0F,从这个地址取出值赋给R@
l         相对寻址
基址寻址的变形,由PC寄存器提供基准地址,指令中地址段作为偏移量.两者相加即是有效地址,以下是BL采用相对寻址
BL NEXT

NEXT
    …
MOV PC,LR ;从子程序返回
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值