ARM System Developer's Guide 学习笔记 3.1 数据处理指令

数据处理指令(Data Processing Instructions)

数据处理指令操控着寄存器中的数据。

包含:数据移动指令,算术运算指令,逻辑运算指令,比较指令和乘法指令。大多数数据处理指令可以通过桶型移位器处理其中一个操作数。

ARM指令集中最大的一族,这族指令的格式相同。如果在数据处理指令中看到 ‘S’ 后缀,那么它将在cpsr(计算机程序状寄存器)中更新标志位。移动和逻辑指令更新 进位标志位 ‘C’ ,取反标志位 ‘N’ , 零标志位 ‘Z’‘C’ 的设置来自上一位移出的结果 ; 将**‘N’** 设置在在结果的31bit上;如果结果为零,设置 ‘Z’

记住,这是一个 load / store架构,这些指令只操作寄存器,而不是内存。

他们在两个操作数上执行特定的操作,并将结果存放到目标寄存器。
第一个操作数总是一个寄存器Rn。
第二个操作数通过barrel shifter送往ALU。

1. 数据移动指令 (MOVE INSTRUCTIONS)

  • 概念:copy N( 寄存器/值 ) 到 目标寄存器 Rd。
  • 常用数据移动指令 及其 语法

常用数据移动指令 及其 语法

  • 例子:
    MOV指令示例

2. 桶型移位器 BARREL SHIFTER

  • 移位:上述N 在 MOV指令中是一个简单的寄存器,它也可以是一个经过桶型移位器预处理的寄存器Rm。

    数据处理指令在算数逻辑单元(ALU内执行),ARM一个独特的特点是可以将32位二进制数在进入ALU之前进行移位,增加了数据处理的灵活性。

  • ARM 微处理器内嵌的桶型移位器(Barrel Shifter),支持数据的各种移位操作

  • 不需要移位器的指令:MUL(multiply),CLZ(count leading zeros), QADD(signed saturated 32-bit add)

  • ALU 和 BARREL SHIFTER
    如图:寄存器Rn不经过预处理进入到ALU。Rm经过预处理进入移位器以后再进入ALU。
    ALU 和 BARREL SHIFTER

  • 例子:寄存器Rm 移动到目标寄存器之前进行逻辑左移logicla shift left(LSL),和标准C语言的 左操作符“<<”是一样的。MOV指令复制左移结果N到寄存器Rd, N代表LSL操作后的结果。

  • 操作示例:
    MOV R0, R1, LSR#2 ;将 R1 中的内容右移两位后传送到 R0 中,左端用零来填充。
    移位前
    将寄存器r5进行逻辑左移2位后送到r7寄存器中。

    十进制5的二进制数值是0101,进行逻辑左移2位就是0001_0100, 也就是十进制中的20。其实每逻辑左移1位就相当于原数值进行乘2操作,5逻辑左移2位其实就是5 x 2^2 = 20。
    移位后

  • 常用移位指令 及其 语法 如下
    常用移位指令 及其 语法

    • ASL 算术左移 :ASL 和 LSL 是等价的,可以自由互换
    • LSR 逻辑右移:LSR 和 ASR 是等价的,可以自由互换
    • ASR 算术右移:MOV R0, R1, ASR#2 ;将 R1 中的内容右移两位后传送到 R0 中,左端用第 31 位的值来填充。
    • ROR 循环右移:MOV R0, R1, ROR#2 ;将 R1 中的内容循环右移两位后传送到 R0 中。
    • RRX 带扩展的循环右移:MOV R0, R1, RRX#2 ;将 R1 中的内容进行带扩展的循环右移两位后传送到 R0 中。

逻辑逐位左移

  • MOVS例子:
    示例

3. 算数运算指令 (ARITHMETIC INSTRUCTIONS)

  • 常用算数运算指令 及其 语法 如下
    N是移位操作后的结果
    常用算数运算指令 及其 语法

  • 1.ADC :带进位加法指令。将N的数据和Rn的值相加,再加上 CPSR 中的C条件标志位,结果保存在Rd寄存器。
    举例如下:

    • ADC R0,R1,#12 ==== R0 = R1 + 12 + C(NZCV标志位)完成64位加法的高位运算
  • 2.ADD : 将N与Rn的值相加,结果保存到Rd寄存器。目标寄存器和操作数是同一个寄存器时,可以省略。
    举例如下:

    • ADD R0, R1, #12 ==== R0 = R1 + 12
    • ADD R0, R1, R2 ==== R0 = R1 + R2
    • ADD R0, #12 ==== R0 = R0 + 12
    • ADD R0, R1 ==== R0 = R0 + r1
    • ADDS R3,R1,R2,LSL #2 ====R3 = R1 + R2 * 4
  • 3.RSB:逆向减法指令。用N-Rn,结果保存在Rd中。
    举例如下:

    • RSB R3,R1,#0xFF00 ==== R3 = #0xFF00 - R3
    • RSBS R1,R2,R2,LSL #2 ==== R1 = R2*4 -R2 = 3R2
    • RSB R0,R1,#0 ==== R0 = #0 - R1 = -R1
      RSB示例,16进制,需要借位,可以用这个指令进行取反操作
  • 4.RSC:带进位的逆向减法指令,用N减去N,再减去CPSR 中的C条件标志位,结果保存在Rd寄存器。
    举例如下:

    • RSC R0,R1,#12 ==== R0 = 12 - R1 - C(NZCV标志位)完成64位减法的高位运算
  • 5.SBC : 带进位的减法指令。Rn减去N,再减去CPSR 中的C条件标志位的 非(若C标志清零,结果再减去1),结果保存在Rd寄存器。
    举例如下:

    • SBC R0,R1,#12 ==== R0 = R1 - 12 - !C(NZCV标志位)完成64位减法的高位运算
  • 6.SUB : 减法指令,寄存器Rn 减去 N ,结果保存在Rd中。
    举例如下:

    • SUBS R0, #1 ==== R0 = R0 - 1
    • SUBS R2,R1,R2 ==== R2 = R1 - R2
    • SUB R6,R7,#0X10 ==== R6 = R7 - #0X10
      SUB示例

SUBS示例,指令执行前
SUBS示例,指令执行后,更新cprs标志位 ZC

4. 使用移位器进行算数运行指令

  • 概念:第二个操作数移位的广泛在算数和逻辑运算可用是ARM一个特征。
  • 示例:
    r1寄存器首先向左移动一位,得到了2倍r1值以后通过ADD指令加上移位后的结果,最终结果保存在r0寄存器上。

算数移位示例,16进制中f表示15

5. 逻辑运算指令(Logical Instructions)

  • 概念:逻辑指令在两个源寄存器中执行按位逻辑操作。
  • 常用逻辑运算指令 及其 语法 如下

常用逻辑运算指令 及其 语法

  • OR 指令示例:
    逻辑 或 指令 执行前

逻辑 或 指令 执行后

  • BIC 指令示例:

逻辑 位清楚指令即 与非 操作 示例

6. 比较指令(Comparison Instruction)

  • 概念:比较指令用于用一比较或测试一个32位寄存器的值。根据比较结果更新cpsr寄存器的标志位,但是不影响其他寄存器。当标志位设置以后,通过执行条件信息可以被用到程序的执行流图中。不需要使用后缀’S’来更新标志位。
  • 常见的比较指令 及其 语法 如下
    比较指令执行后根据结果来修改NZCV。

常见的比较指令 及其 语法

cmp :比较, 适合所有条件 ;
cmn :cmp的扩展,快速判断两个数是否相反数;
teq :判断相等,只能和NE或EQ使用;
tst :位测试, 判断第一操作数,第二操作数为1的那些位是0还是1

  • CMP 指令示例:执行指令前,r0 和 r9 寄存器相等。比较指令执行以后标志位Z由 0 变为 1(由小写z 变成大写 Z),这表示两个寄存器的值相等。

CMP指令

7. 乘法指令(Multiply Instructions)

  • 概念:乘法指令将一对儿寄存器的内容相乘。长整型需要一对寄存器,长整型命令格式(结果为64位)。
  • 常用乘法指令 及其 语法 如下

常用乘法指令 及其 语法

**其中:**长整型指令(SMLAL, UMLAL, SMULL, UMULL)产生64位结果。这个结果很大和32位寄存器不匹配,设置为两个寄存器 RdLo和RdHo,RdLo保存64位结果的低32位,RdHo64位结果的高32位。

  • MUL指令示例:

 MUL指令示例

  • UMULL指令示例:

UMULL无符号长整型乘法指令示例

发布了45 篇原创文章 · 获赞 4 · 访问量 2518

猜你喜欢

转载自blog.csdn.net/keke_Memory/article/details/105561115