ARM指令寻址方式之: 数据处理指令的寻址方式

2024-05-14 06:41:59

4.1  数据处理指令的寻址方式

4.1.1  数据处理指令的寻址方式概要

数据处理指令的基本语法格式如下。

<opcode> {<cond>} {S} <Rd>,<Rn>,<shifter_operand>

其中<shifter_operand>有下面11种形式,如表4.1所示。

表4.1        <shifter_operand>的寻址方式

语    法

寻 址 方 式

1

#<immediate>

立即数寻址

2

<Rm>

寄存器寻址

3

<Rm>, LSL  #<shift_imm>

立即数逻辑左移

4

<Rm>, LSL  <Rs>

寄存器逻辑左移

5

<Rm>, LSR  #<shift_imm>

立即数逻辑右移

6

<Rm>, LSR  <Rs>

寄存器逻辑右移

7

<Rm>, ASR  #<shift_imm>

立即数算术右移

8

<Rm>, ASR  <Rs>

寄存器算术右移

9

<Rm>, ROR  #<shift_imm>

立即数循环右移

10

<Rm>, ROR  <Rs>

寄存器循环右移

11

<Rm>, RRX

寄存器扩展循环右移

数据处理指令的寻址方式根据<shifter_operand>的不同,相应的分为11种。

4.1.2  指令解码

图4.1显示了数据处理指令不同寻址方式下的解码格式。

图4.1  数据操作指令编码格式

编码格式中各域含义如下。

·  <opcode>:确定具体指令。

·  S:标识指令是否影响程序状态寄存器CPSR条件标志。

·  Rd:指令操作的目的寄存器。

·  Rn:指令第一源操作数。

·  bit[11∶0]:移位操作,详见本章移位操作一节。

·  bit[25]:被用来区分是立即数移位操作还是寄存器移位操作。

如果指令编码出现下面情况:bit[25] = 0并且bit[4] = 1并且bit[7] = 1,则指令并非数据处理指令,它可能是Load/Store指令或算术指令。

4.1.3  移位操作

数据处理指令是在算术逻辑单元ALU中完成。ARM处理器一个显著特征就是可以在操作数进入ALU之前,对操作数进行指定位数的左移或右移操作。这种功能明显增强了数据处理操作的灵活性。

移位操作可能产生进位,更新程序状态寄存器CPSR的进位标志C。移位操作有下面3种基本方式。

1.立即数方式

没有任何一条ARM指令可以包含一个32位的立即数,数据处理指令编码格式中,第二个操作数有12位。指令的编码格式如图4.1所示。

指令中的立即数是由一个8 bit的常数移动4 bit偶数位(0,2,4,…,26,28,30)得到的。所以,每一条指令都包含一个8 bit的常数X和移位值Y,得到的立即数=X循环右移(2×Y)。

注意

8位立即数一定要移偶数位。

下面列举了一些有效的立即数。

0xFF、0x104、0xFF0、0x FF00、0x FF000、0x FF000000、0x F000000F

下面是一些无效的立即数。

0x101、0x102、0x FF1、0x FF04、0x FF003、0x FFFFFFFF、0x F000001F

下面是一些应用立即数的指令。

MOV  r0,#0                 ;送0到r0

ADD  r3,r3,#1              ;r3的值加1

CMP  r7,#1000               ;r7的值和1000比较

BIC  r9,r8,#0x FF00         ;将r8中8~15位清零,结果保存在r9中

2.寄存器方式

寄存器的值可以被直接用于数据操作指令,如:

MOV  r2,r0                  ;r0的值送r2

ADD  r4,r3,r2               ;r2加r3,结果送r4

CMP  r7,r8                  ;比较r7和r8的值

3.寄存器移位方式

寄存器的值在被送到ALU之前,可以事先经过桶形移位寄存器的处理。预处理和移位发生在同一周期内,所以有效的使用移位寄存器,可以增加代码的执行效率。

具体的移位(或者循环移位)方式有下面几种。

·  ASR:算术右移。

·  LSL:逻辑左移。

·  LSR:逻辑右移。

·  ROR:循环右移。

·  RRX:扩展的循环右移。

以上5种移位方式,移位值均可以由立即数或寄存器指定。下面是一些在指令中使用了移位操作的例子。

ADD  r2,r0,r1,LSR  #5

MOV  r1,r0,LSL  #2

RSB  r9,r5,r5,LSL  #1

SUB  r1,r2,r0,LSR #4

MOV  r2,r4,ROR  r0

4.1.4  寻址方式分类详解

数据处理指令的寻址方式根据<shifter_operand>的不同,相应的分为11种。详见表4.1。下面对各类寻址方式进行详细说明。

1.#<immediate>

(1)编码格式

指令的编码格式如图4.2所示。

图4.2  数据处理指令——立即数寻址编码格式

立即数寻址为数据处理指令提供了一个可直接操作的立即数。立即数的生成方法见前面章节介绍。如果移位值为0,则移位进位值为程序状态寄存器CPSR的C标志位;否则,为32-bit立即数的bit[31]。

(2)操作伪代码

Shifter_operand = immed_8 Rotate_Right (rotate_imm*2)

if  rotate_imm == 0 then

shifter_carry_out = C flag

else  /* rotate_imm != 0*/

shifter_carry_out = shifter_operand[31]

(3)说明

① 并不是所有的32-bit立即数都是可以使用的合法立即数。只有那些通过将一个8-bit的立即数循环右移偶数位可以得到的立即数才可以在指令中使用。

② 有些立即数可以通过不止一种方法得到。由于立即数的构造方法中移位包含了循环操作,而循环移位操作会影响CPSR的条件标志位C。因此,同一个合法的立即数由于采用了不同的编码方式,将使这些指令的执行产生不同的结果,这是不能允许的。ARM汇编器按照下面的规则来生成立即数的编码。

·  当立即数数值在0和0xFF范围时,令immed_8=<immediate>,immed_4=0。

·  其他情况下,汇编编译器选择使用immed_4数值最小的编码方式。

③  为了更精确地控制立即数的生成,可以使用下面的语法格式控制立即数的生成。

#<immed_8>,<rotate_amout>

其中,<rotate_amout> = 2*rotate_imm

(4)举例

SUBS  r0,r0,#1                      ;寄存器r0中的数值减1,结果保存到r0

MOV  r0,#0xff00     ; 0xff00 → r0      ;将立即数0xff00放入r0保存

2.<Rm>

(1)编码格式

指令的编码格式如图4.3所示。

图4.3  数据处理指令——寄存器寻址编码格式

指令的操作数即为寄存器中的数值。移位寄存器的进位为程序状态寄存器CPSR的C标志位。

指令的语法格式为:<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>

(2)操作伪代码

Shifter_operand = Rm

Shifter_carry_out = C Flag

(3)说明

① 从指令的解码格式来看,寄存器寻址方式和使用立即数逻辑左移寻址解码格式是相同的,只是其移位数为0。

② 如果指令中的Rm或Rn指定为程序计数器r15,则操作数的值为当前指令地址加8。

(4)举例

MOV  r1,r2    ; r2 → r1

SUB  r0,r1,r2   ; r1 – r2 → r0

3.<Rm>, LSL  #<shift_imm>

(1)编码格式

指令的编码格式如图4.4所示。

图4.4  数据处理指令——立即数逻辑左移寻址编码格式

指令的操作数为寄存器Rm的数值逻辑左移shift_imm位。左移的范围在0到31之间。左移移出的位用0补齐。进位标志位是最后移出的位(如果移位数为0,则为C标志位)。

指令的语法格式为:<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,LSL #<shift_imm>,其中:

·  <Rm>为进行逻辑左移操作的寄存器;

·  LSL为逻辑左移操作标识;

·  <shift_imm>为逻辑左移位数,范围为0~31。

(2)操作伪代码

if  shift_imm == 0 then /*执行寄存器操作*/

shifter_operand = Rm

shifter_carry_out = C flag

else  /*移位寄存器大于零*/

shifter_operand = Rm logical_shift_left shift_imm

shifter_carry_out = Rm[32 – shift_imm]

(3)说明

① 如果移位立即数<shift_imm> =0,则该寻址方式为立即数直接寻址。

② 如果指令中的Rm或Rn指定为程序计数器r15,则操作数的值为当前指令地址加8。

(4)举例

SUB r0,r1,r2,LSL #10        ;r1的值减去r2的值左移10bit,结果放到r0寄存器

MOV r0,r2,LSL #3            ;r2的值左移3bit,结果放入r0,即r0 = r2×8

4.<Rm>, LSL  <Rs>

(1)编码格式

指令的编码格式如图4.5所示。

图4.5  数据处理指令——寄存器逻辑左移寻址编码格式

寄存器逻辑左移十分适合寄存器值乘2的倍数操作。

这个指令是将寄存器Rm的值逻辑左移一定的位数。位移的位数由Rs的最低8位bit[7∶0]决定。Rm移出的位用0补齐。进位值是移位寄存器最后移出的位,如果移位数大于0,则进位值为0。

(2)语法格式

<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,LSL  <Rs>

其中:

·  <Rm>为指令被移位的寄存器;

·  LSL为逻辑左移操作标识;

·  <Rs>为包含逻辑左移位数的寄存器。

(3)操作伪代码

if  Rs[7:0] = = 0 then

shifter_operand = Rm

shifter_carry_out = C flag

else  if  Rs[7:0] < 32 then

shifter_operand = Rm  logical_shift_left  Rs[7:0]

shifter_carry_out = Rm[32 – Rs[7:0]]

else  if  Rs[7:0] = = 32 then

shifter_operand = 0

shifter_carry_out = Rm[0]

else  /*Rs的后8位大于零*/

shifter_operand = 0

shifter_carry_out = 0

(4)说明

如果程序计数器r15被用作Rd,Rm,Rn或Rs中的任意一个,则指令的执行结果不可预知。

(5)举例

MOV  r0,r2,LSL r3          ;r2的值左移r3位,结果放入r0

ANDS r1,r1,r2,LSL r3      ;r2的值左移r3位,然后和r1相与,结果放入r1

5.<Rm>, LSR #<shift_imm>

(1)编码格式

指令的编码格式如图4.6所示。

图4.6  数据处理指令——立即数逻辑右移寻址编码格式

指令的操作数为寄存器Rm的值右移<shift_imm>位,相当于Rm的值除以一个2的倍数。<shift_imm>值的范围为0~31,移位后空出的位添0。循环器进位值为Rm最后移出的位。

(2)语法格式

<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,LSR #<shift_imm>

其中:

·  <Rm>为被移位的寄存器;

·  LSR为逻辑右移操作标识;

·  <shift_imm>为逻辑右移位数,范围为0~31。

(3)操作伪代码

if  shift_imm == 0 then /*执行寄存器操作*/

shifter_operand = 0

shifter_carry_out = Rm[31]

else  /*移位立即数大于零*/

shifter_operand = Rm logical_shift_Right shift_imm

shifter_carry_out = Rm[shift_imm - 1]

(4)说明

① shift_imm的取值范围为0~31,当shift_imm=0时,移位位数为32,所以移位位数范围为1~32位。

② 如果指令中的Rm或Rn指定为程序计数器r15,则操作数的值为当前指令地址加8。

6.<Rm>, LSR  <Rs>

(1)编码格式

指令的编码格式如图4.7所示。

图4.7  数据处理指令——寄存器逻辑右移寻址编码格式

此操作将寄存器Rm的数值逻辑右移一定的位数。移位的位数由Rs的最低8位bit[7∶0]决定。移出的位由0补齐。当Rs[7∶0]大于0而小于32时,进位标志C由最后移出的位决定,当Rs[7∶0]大于32时,进位标志位为0,当Rs[7∶0]等于0时,进位标志不变。

(2)语法格式

<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,LSR  <Rs>

其中:

·  <Rm>为指令被移位的寄存器;

·  LSR为逻辑右移操作标识;

·  <Rs>为包含逻辑右移位数的寄存器。

(3)操作伪代码

if  Rs[7:0] = = 0 then

shifter_operand = Rm

shifter_carry_out = C flag

else  if  Rs[7:0] < 32 then

shifter_operand = Rm  logical_shift_Right  Rs[7:0]

shifter_carry_out = Rm[Rs[7:0] - 1]

else  if  Rs[7:0] = = 32 then

shifter_operand = 0

shifter_carry_out = Rm[31]

else  /*Rs的后8位大于零*/

shifter_operand = 0

shifter_carry_out = 0

(4)说明

如果程序计数器r15被用作Rd、Rm、Rn或Rs中的任意一个,则指令的执行结果不可预知。

7.<Rm>, ASR #<shift_imm>

(1)编码格式

指令的编码格式如图4.8所示。

图4.8  数据处理指令——立即数算术右移寻址编码格式

指令的操作数为寄存器Rm的数值逻辑右移<shift_imm>位。<shift_imm>的值范围为0~31,当<shift_imm>等于0时,移位位数为32,所以移位位数范围为1~32位。进位移位操作后,空出的位添Rm的最高位Rm[31]。进位标志为Rm最后被移出的数值。

(2)语法格式

<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,ASR #<shift_imm>

其中:

·  <Rm>为被移位的寄存器;

·  ASR为算术右移操作标识;

·  <shift_imm>为算术右移位数,范围为1~32,当shift_imm等于0时移位位数为32。

(3)操作伪代码

if  shift_imm == 0 then /*执行寄存器操作*/

if  Rm[31] = = 0 then

shifter_operand = 0

shifter_carry_out = Rm[31]

else /*Rm[31] = = 1*/

shifter_operand = 0xffffffff

shifter_carry_out = Rm[31]

else  /*shift_imm > 0*/

shifter_operand = Rm Arithmetic_shift_Right <shift_imm>

shifter_carry_out = Rm[shift_imm - 1]

(4)说明

① 如果指令中的Rm或Rn指定为程序计数器r15,则操作数的值为当前指令地址加8。

8.<Rm>, ASR  <Rs>

(1)编码格式

指令的编码格式如图4.9所示。

图4.9  数据处理指令——寄存器算术右移寻址编码格式

此操作将寄存器Rm的数值算术右移一定的位数。移位后空缺的位由Rm的符号位(Rm[31])填充。位移的位数由Rs的最低8位bit[7∶0]决定。当Rs[7∶0]大于零而小于32时,指令的操作数为寄存器Rm的数值算术右移Rs[7∶0]位,进位标志C为Rm最后被移出的位。

(2)语法格式

<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,ASR  <Rs>

其中:

·  <Rm>为指令被移位的寄存器;

·  ASR为算术右移操作标识;

·  <Rs>为包含算术右移位数的寄存器。

(3)操作伪代码

if  Rs[7:0] = = 0 then

shifter_operand = Rm

shifter_carry_out = C flag

else  if  Rs[7:0] < 32 then

shifter_operand = Rm  Arithmeticl_shift_Right  Rs[7:0]

shifter_carry_out = Rm[Rs[7:0] - 1]

else

if  Rm[31] = =0 then

shifter_operand = 0

shifter_carry_out = Rm[31]

else

shifter_operand = 0xffffffff

shifter_carry_out = Rm[31]

(4)说明

如果程序计数器r15被用作Rd、Rm、Rn或Rs中的任意一个,则指令的执行结果不可预知。

9.<Rm>, ROR #<shift_imm>

(1)编码格式

指令的编码格式如图4.10所示。

图4.10  数据处理指令——立即数循环右移寻址编码格式

指令的操作数由寄存器Rm的数值循环右移一定的位数得到。移位的位数由Rs的最低8位bits[7∶0]决定。当Rs[7∶0]=0时,指令的操作数为寄存器Rm的值,循环器的进位值为CPSR中的C条件标志位;否则,循环器的进位值为Rm最后被移出的位。

(2)语法格式

<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,ROR #<shift_imm>

其中:

·  <Rm>为被移位的寄存器;

·  ROR为循环右移操作标识;

·  <shift_imm>为循环右移位数,范围为1~31,当shift_imm等于0时执行RRX操作。

(3)操作伪代码

if  shift_imm == 0 then /*执行寄存器操作*/

执行RRX操作

else

shifter_operand = Rm Rotate_Right shift_imm

shifter_carry_out = Rm[shift_imm - 1]

(4)说明

如果指令中的Rm或Rn指定为程序计数器r15,则操作数的值为当前指令地址加8。

10.<Rm>, ROR  <Rs>

(1)编码格式

指令的编码格式如图4.11所示。

图4.11  数据处理指令——寄存器循环右移寻址编码格式

指令的操作数由寄存器Rm的数值循环右移一定的位数。移位的位数由Rs的最低8位bits[7∶0]决定。当Rs[7∶0]=0时,指令的操作数为寄存器Rm的值,循环器的进位值为CPSR中的C条件标志位;否则,循环器的进位值为Rm最后被移出的位。

(2)语法格式

<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,ROR  <Rs>

其中:

·  <Rm>为指令被移位的寄存器;

·  ROR为循环右移操作标识;

·  <Rs>为包含循环右移位数的寄存器。

(3)操作伪代码

if  Rs[7:0] = = 0 then

shifter_operand = Rm

shifter_carry_out = C flag

else  if  Rs[4:0] == 0 then

shifter_operand = Rm

shifter_carry_out = Rm[31]

else

shifter_operand = Rm Rotate_Right Rs[4:0]

shifter_carry_out = Rm[Rs[4:0] - 1]

(4)说明

如果程序计数器r15被用作Rd、Rm、Rn或Rs中的任意一个,则指令的执行结果不可预知。

11.<Rm>, RRX

(1)编码格式

指令的编码格式如图4.12所示。

图4.12  数据处理指令——扩展右移寻址编码格式

指令的操作数为寄存器Rm的数值右移一位,并用CPSR中的C条件标志位填补空出的位。CPSR中的C条件标志位则用移出的位代替。

(2)语法格式

<opcode> {<cond>} {S} <Rd>,<Rn>,<Rm>,RRX

其中:

·  <Rm>为指令被移位的寄存器;

·  RRX为扩展的循环右移操作。

(3)操作伪代码

shifter_operand = (C flag logical_shift_left 31) OR (Rm logical_shift_Right 1)

shifter_carry_out = Rm[0]

(4)说明

① 此种寻址方式的编码形式和“ROR #0”一致。

② 如果程序计数器r15被用作Rd、Rm、Rn或Rs中的任意一个,则指令的执行结果不可预知。

③ 可以实现ADC指令的功能。

参考网址:http://www.eefocus.com/embedded/322868/r1

ARM指令寻址方式之: 数据处理指令的寻址方式相关推荐

  1. 汇编(二)——ARM数据处理指令——算术运算、数据传送

    ARM指令集 数据操作 ARM指令的种类 数据处理指令 程序状态寄存器与通用寄存器之间的传送指令 Load/Store指令 转移指令 异常中断指令 协处理器指令 数据处理指令分为6类 数据传送指令 算 ...

  2. ARM汇编指令(ARM寻址方式、汇编指令、伪指令

    1.寻址方式 所谓寻址方式就是:处理器根据指令中给出的地址信息来寻找物理地址的方法. 1)立即寻址 立即寻址也叫立即数寻址,这是一种特殊的寻址方式,操作数本身就是在指令中给出的. 只要取出指令也就是取 ...

  3. 微型计算机寻址方式命令,寻址方式与基本指令-微机原理实验报告.docx

    西安郵電大學 微型计算机原理 课内实验报告书 院系名称 : 计算机学院 实验题目 : 寻址方式与基本指令 学生姓名 : 专业名称 : 软件工程 班 级 : 软件1003班 学号 : 指导教师 : 葛茂 ...

  4. 微机原理学习笔记——寻址方式和传送指令(MOV)

    目录 操作数的寻址方式 立即数寻址方式 寄存器寻址方式 存储器寻址方式 段超越前缀指令 直接寻址方式 寄存器间接寻址方式 寄存器相对寻址方式 基址变址寻址方式 相对基址变址寻址方式 存储器寻址方式中的 ...

  5. 8086汇编语言寻址方式、基本指令和调试指令

    一.80x86/Pentium 各种寻址方式 1.立即寻址 立即寻址方式下,操作数作为立即数直接包含在指令中,紧跟在操作码之后与其一起 存放在代码段区域.因此,立即数总是和操作码一起被存入 CPU 的 ...

  6. 总结:常用的通用数据处理指令

    作者:bakari  时间:2012.4.21 1. 操作数类型 Imm立即操作数 Reg寄存器操作数 Mem内存操作数 2. 操作数寻址方式 立即数寻址 寄存器数寻址 存储器寻址 3. 数据传送类指 ...

  7. ARM汇编之跳转指令

    ARM汇编语言之跳转指令 前言 ARM架构在当今主流的芯片中无论是MCU还是SOC都占有很大的市场,因此基于ARM架构的汇编语言对于嵌入式软件开发人员而言,其实也是一项必须掌握的基本功. " ...

  8. 【ARMv8 编程】A64 数据处理指令——算术指令

    许多在应用程序级别编写代码的程序员不需要用汇编语言编写代码.然而,汇编代码在需要高度优化的代码的情况下很有用.在编写编译器时,或者需要使用 C 语言中无法直接提供的底层特性时,都会出现这种情况.部分引 ...

  9. ARM平台下独占访问指令LDREX和STREX的原理与使用详解

    为了实现线程间同步,一般都要在执行关键代码段之前加互斥(Mutex)锁,且在执行完关键代码段之后解锁.为了实现所谓的互斥锁的概念,一般都需要所在平台提供支持. 在计算机领域里,如果要在多线程的情况下要 ...

最新文章

  1. cnpm install -g generator-gulp-webapp yo gulp-webapp test-gulp-webapp
  2. 2019年十大数据与分析技术趋势
  3. 进程文件: cidaemon or cidaemon.exe
  4. 160个Crackme014
  5. 杭电1421java实现
  6. python json有什么用_为什么要学习用Python解析JSON数据?
  7. SSL/TLS协议运行机制
  8. 英国电信公司沃达丰遭到网络攻击
  9. 【运维安全】-MySQL手工注入
  10. 【mysql】使用脚本对mysql状态进行监控
  11. tkinter GUI 客户端页面编程 登录注册案例开发
  12. 方程组变换+初等变换+矩阵等价+克莱姆法则
  13. 磁盘 I/O 和网络
  14. 网渲显示服务器错误,网络渲染疑难解答指南 | 3ds Max 2021 | Autodesk Knowledge Network...
  15. 英伟达面向开发者群体建立深度学习课程
  16. sec^3 不定积分
  17. RollBack RX Professional 设置快照教程
  18. java计算机毕业设计vue.js开发红酒网站源码+mysql数据库+系统+lw文档+部署
  19. 浙江大学工程师学院篇|2022年电子信息/通信工程夏令营保研/考研复试经验贴
  20. (C语言)求最大公约数的四个方法

热门文章

  1. Js+DVML:很酷实用的右键弹出菜单
  2. UDDI :一种 XML Web 服务
  3. 特效html布局,一些好玩的css特效
  4. wow服务器已满 队列位置5,《魔兽世界》前夕版本中“碧空之歌”排队人数近万,有必要排吗?...
  5. Java黑皮书课后题第6章:6.37(格式化整数)编写一个测试程序,提示用户输入一个数字以及宽度,显示通过调用format方法返回的字符串
  6. Java黑皮书课后题第2章:2.12(物理:求出跑道长度)编写程序,提示用户输入以米/秒为单位的速度v和加速度a,然后显示最短跑道长度
  7. java将jfif格式转换成ipg_win10系统将jfif格式转jpg的操作方法
  8. Oracle导入导出数据
  9. 学霸网站-Beta版本发布说明
  10. 九度 1531:货币面值(01背包)