ARM指令系统
ARM指令系统
ARM指令的分类
跳转指令、数据处理指令、程序状态寄存器(PSR)传输指令、Load/Store指令、协处理器指令和异常产中断产生指令,6大类。
ARM指令编码格式
ARM指令字长为固定的32位,一条典型的ARM指令编码格式如下:
cond 指令执行的条件编码;
opcode 指令操作符编码;
S 决定指令的操作是否影响CPSR的值;
Rd 目标寄存器编码;
Rn 包含第1个操作数的寄存器编码;
operand2 表示第2个操作数;
ARM指令语法格式
一条典型的ARM指令语法格式如下
<opcode> {<cond>} { S } <Rd> , < Rn > {, <operand2> }
其中:
cond:指令执行的条件,如EQ、NE等;
opcode:指令助记符,如ADD、LDR、STR等;
S:决定指令的操作是否影响CPSR寄存器的值;
Rd:目标寄存器;
Rn:第一个操作数的寄存器;
operand2:第二个操作数;
<>内的项是必选项, {}内的项是可选项, {<cond>}为指令执行条件,是可选的,如果不写则使用默认条件AL(无条件执行)。
指令的条件码<cond>的含义和助记符
ARM指令寻址方式
寻址方式:处理器根据指令中给出的地址信息来寻找物理地址的方式。
1. 数据处理指令的操作数的寻址方式
数据处理指令的格式:
<opcode> {<cond>} { S } <Rd> , < Rn > {, <operand2> }
立即数寻址
每个立即数由一个8位的常数循环右移偶数位得到。其中循环右移的位数由一个4位二进制的两倍表示。如果立即数记作<immediate>,8位常数记作immed_8,4位的循环右移值记作rotate_imm,则有<immediate> = immed_8 循环右移(2*rotate_imm),这样并不是每一个32位的常数都是合法的立即数,只有能够通过上面构造方法得到的才是合法的立即数。(具体怎么算的暂不深究,知道有这么回事就行)按照上面的构造方法,一个合法的立即数可能有多种编码方式。由于这种立即数的构造方法中包含了循环移位操作,而循环移位操作会影响CPSR的条件标志位C。因此,同一个合法的立即数由于采用了不同的编码方式,将使某些指令的执行产生不同的结果,这显然shiite不能允许的。ARM汇编编译器按照下面的的规则来生成立即数的编码。
- 当立即数值在0和0xFF范围时,令immed_8 = <immediate>,rotate_imm = 0;
- 其他情况下,汇编编译器选择使rotate_imm数值最小的编码方式;
对立即数寻址简单的理解方式:
操作数本身就在指令中给出,只要取出指令也就取到了操作数。
在以上两条指令中,第二个操作数即为立即数,要求以“#”为前缀,对于以十六进制表示的立即数,还要求在"#"后加上"0x"或"&"。
寄存器寻址
利用寄存器中的数值作为操作数,这种寻址方式是各类微处理其经常采用的一种方式,也是一种执行效率较高的寻址方式。
MOV R3,R2 ;将R2的数值放到R3中
ADD R0,R1,R2 ;将寄存器R1和R2的内容相加,其结果存放在寄存器R0中
寄存器移位寻址
ARM指令集特有的寻址方式,当第2操作数是寄存器移位方式时,第2个寄存器操作数在与第1个操作数结合之前,选择进行移位操作。
MOV R0,R2,LSL #3 ;该指令将R2的值左移3位,结果放入R0。
可采用的一位操作如下:
LSL:逻辑左移(logical shift left),寄存器中字的低端空出的位补0;
LSR:逻辑右移(logical shift right),寄存器中的高端空出的位补0;
ASR:算术右移(arithmetic shift right),移位过程中保持符号位不变,即如果源操作数为正数,则字的高端空出的位补0,否则补1。
ROR:循环右移(rotate right),由字的低端移出的位填入字的高端空出的位。
RRX:带扩展的循环右移(rotate right extended by lplace),操作数右移一位,高端空出的位用原C标志值填充。
2. 字及无符号字节的Load/Store指令的寻址方式
Load指令用于从内存中读取数据放入寄存器中;Store指令用于将寄存器中的数据保存到内存。Load/Store指令的寻址方式由两部分组成,一部分为一个基址寄存器,另一部分为一个地址偏移量。基址寄存器可以为任一个通用寄存器;
地址偏移量可以有以下三种格式:
立即数 立即数可以是一个无符号的数值,这个数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值;
寄存器 寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值;
寄存器及一个移位常数 这种格式由一个通用寄存器和一个立即数组成,寄存器中的数值可以根据指令中的移位标志及移位常数作一定的移位操作生成一个地址偏移量。这个地址偏移量可以加到基址寄存器,也可以从基址寄存器中减去这个数值;
寻址方式的地址计算方法也有三种:
偏移量方法 基址寄存器中的值和地址偏移量作加减运算,生成操作数的地址;
事先更新方法 基址寄存器中的值和地址偏移量作加减运算,生成操作数的地址;指令执行后,这个生成的操作数地址被写入基址寄存器;
事后更新方法 指令将基址寄存器的值作为操作数的地址执行内存访问。基址寄存器中的值和地址偏移量做加减运算,生成操作数的地址;指令执行后,这个生成的操作数地址被写入基址寄存器;
寄存器间接寻址
以寄存器中的值作为操作数的地址,而操作数本身存放在存储器中。
在第一条指令中,以寄存器R2的值作为操作数的地址,在存储器中取得一个操作数后与R1相加,结果存入寄存器R0中。
指令将以R1的值为地址的存储器中的数据传送到R0中。
基址变址寻址
将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址。
在第一条指令中,将寄存器R1的内容加上4形成操作数的有效地址,从而取得操作数存入寄存器R0中;
在第二条指令中,将寄存器R1的内容加上4形成操作数的有效地址,从而取得操作数存入寄存器R0中,然后,R1的内容自增4个字节;
在第三条指令中,以寄存器R1的内容作为操作数的有效地址,从而取得操作数存入寄存器R0中,然后,R1的内容自增4个字节;
在第四条指令中,将寄存器R1的内容加上寄存器R2的内容形成操作数的有效地址,从而取得操作数存入寄存器R0中;
3. 杂类Load/Store指令的寻址方式
4. 批量Load/Store指令的寻址方式
5.协处理器Load/Store指令的寻址方式