ARM指令浅析1(mov、ldr)
1.环境及优化项
采⽤-O2优化选项,通过arm处理器架构下的gcc编译器编译⽤例⽣成汇编码查看其⽣成的指令。⾄于为什么⽤O2选项,是因为在某些⽤例中,加⼊-O3选项之后,arm处理器架构下gcc编译器⽣成的汇编会变得更加复杂(⽐如⼀个简单的循环)。
2.ARM指令格式
先简单地介绍⼀下ARM的指令格式,与x86(Intel)架构和alpha架构下有所不同。
基本格式
<opcode> { <cond>} {S} <Rd> , <Rn> , {<opcode2>}
其中,<>内的项是必须的,{}内的项是可选的,⽐如<opcode>是指令助记符,是必须的,⽽{<cond>}为 指令执⾏条件,是可选的,如果不写则使⽤默认条件AL(⽆条件执⾏)。
格式含义
Opcode指令助记符,如LDR,STR 等
Cond执⾏条件,如EQ,NE 等
S是否影响CPSR 寄存器的值,书写时影响CPSR,否则不影响
Rd⽬标寄存器
Rn第⼀个操作数的寄存器x86架构和arm架构区别
operand2第⼆个操作数
指令格式举例如下
LDR  R0,[R1] ;      读取R1 地址上的存储器单元内容,执⾏条件AL(⽆条件执⾏)
ADDS  R1,R1,#1 ;    加法指令,R1+1=R1 影响CPSR 寄存器,带有S
SUBNES R1,R1,#0xD;  条件执⾏减法运算(NE),R1-0xD=>R1,影响CPSR 寄存器,带有S
Arm存储器访问指令
ARM 处理器是加载/存储体系结构的典型的RISC处理器,对存储器的访问只能使⽤加载和存储指令实现。ARM 的加载/存储指令是可以实现字、半字、⽆符/有符字节操作。
ARM 处理器是冯诺依曼存储结构,程序空间、RAM 空间及IO 映射空间统⼀编址,除对RAM 操作以外,对外围IO、程序数据的访问均要通过加载/存储指令进⾏。
这⾥以最常⽤的LDR和STR为例:
LDR 和STR:
加载/存储字和⽆符号字节指令。使⽤单⼀数据传送指令(STR和LDR)来装载和存储单⼀字节或字的数据从寄存器到内存。LDR指令⽤于从内存中读取数据放⼊寄存器中;STR指令⽤于将寄存器中的数据保存到内存。
指令格式如下:
LDR  {cond}  Rd,  <;地址>;
加载指定地址上的数据(字),放⼊Rd 中。
STR  {cond}  Rd,  <;地址>;
存储数据(字)到指定地址的存储单元,要存储的数据在Rd中.
其中,cond为条件。
LDR/STR 指令寻址是⾮常灵活的,由两部分组成,⼀部分为⼀个基址寄存器,可以为任⼀个通⽤寄存器,另⼀部分为⼀个地址偏移量。地址偏移量有以下3 种格式:
(1) ⽴即数。⽴即数可以是⼀个⽆符号数值,这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。指令举例如下:
LDR  R1,  [R0,#0x12] ;
将R0+0x12 地址处的数据读出,保存到R1中(R0 的值不变)
LDR  R1,  [R0,#-0x12];
将R0-0x12 地址处的数据读出,保存到R1中(R0 的值不变)
LDR R1,[R0] ;将R0 地址处的数据读出,保存到R1 中(零偏移)
(2)寄存器。寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。指令举例值。
指令举例如下:
LDR  R1,  [R0,R2] ;
将R0+R2 地址的数据计读出,保存到R1中(R0 的值不变)
LDR  R1,  [R0,-R2] ;
将R0-R2 地址处的数据计读出,保存到R1中(R0 的值不变)
(3)寄存器及移位常数。寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。指令举例如下:
LDR  R1,  [R0,R2,LSL #2] ;
将R0+R2*4地址处的数据读出,保存到R1中(R0,R2的值不变)
⾸先是最简单的⽤例test1:
⽣成的汇编test1.s如下所⽰:
ARM⽣成对应指令指令作⽤
Mov将⽴即数2存储到w2寄存器
Adrp相当于取了⼀个页的基址,以此来偏移寻址
Str将w2寄存器中的数据存到x1中
Ret main函数结束时的返回值
现在来看⼀下arm指令集中的mov指令:
ARM中的mov指令属于数据处理指令中的⼀种,数据处理指令⼤致可分为3 类:数据传送指令(如MOV),算术逻辑运算指令(如ADD,SUM,AND),⽐较指令(如CMP)。数据处理指令只能对寄存器的内容进⾏操作。
所有ARM 数据处理指令均可选择使⽤S 后缀,以影响状态标志。⽐较指令CMP、CMN、TST和TEQ不需要后缀S,它们会直接影响状态标志。
MOV
数据传送指令。将⽴即数或寄存器(operant2)传送到⽬标寄存器Rd,可⽤于移位运算等操作。指令格式如下:
MOV  {cond}  {S}  Rd,  operand2
MOV 指令举例如下:
MOV  R1    #0x10 ;              R1=0x10
MOV  R0,    R1 ;                R0=R1
MOVS  R3,  R1,  LSL  #2 ;        R3=R1<<2,并影响标志位
在这⾥先讲⼀下arm编译器中mov指令与ldr指令的区别:
MOV是从⼀个寄存器或者移位的寄存器或者⽴即数的值传递到另外⼀个寄存器。从本质上是寄存器到寄存器的传递,可以传递⽴即数.在ARM官⽅的⼿册中,mov指令⼀共有五种⽤法。
第⼀种:
第⼀种⽤法就是上述⽤例中的⽤法,将⽴即数2存到w2寄存器中,这⾥的mov指令就等同于⼀条add(immediate)指令。
在该条mov指令中有如下介绍:
MOV<Wd|WSP>, <Wn|WSP>
is equivalent to
ADD<Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}
意思就是wn+#imm=wd
这⾥的imm⼀共有12位。
第⼆种:
这⾥的mov是取⼀个反向的16位⽴即数,等价于MOVN指令。
第三种:
这⾥的mov是取⼀个反向的16位⽴即数,等价于MOVN指令。
第四种:
这⾥的mov指令是取⼀个bitmask⽴即数,等价于ORR(immediate)指令。
第五种:
这⾥的mov指令是寄存器到寄存器之间的传递,等价于ORR(shifted  register)指令。LDR

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。