ARM微处理器编程|指令系统-算术指令

文章目录

  • ARM指令
    • 指令分区
    • 指令可选后缀
      • S 后缀
      • !后缀
      • B 后缀 / H 后缀
      • T 后缀
      • 条件后缀
  • 指令类型
    • 跳转指令
      • 实现跳转的两种方法
      • 跳转指令的编码
      • B 指令
      • BL 指令
      • 条件跳转
      • BX指令
      • BLX 指令
      • 子程序的返回方法
    • 数据处理指令
      • 数据搬移
        • MOV 指令
        • MVN 指令
      • 比较指令
        • CMP 指令
        • CMN 指令
        • TST 指令
        • TEQ 指令
      • 算术指令
        • ADD 指令
        • ADC 指令
        • SUB 指令
        • SBC 指令
        • RSB 指令
        • RSC 指令
      • 逻辑指令
        • AND 指令
        • ORR 指令
        • EOR 指令
        • BIC 指令
      • 乘法指令与乘加指令
        • MUL 指令
        • MLA 指令
        • SMULL 指令
        • SMLAL 指令
        • UMULL 指令
        • UMLAL 指令

ARM指令

指令分区

在这里插入图片描述

  • ARM指令代码一般可以分为五个域
    • 条件码域[31:28] ,4位条件码共有16种组合
    • 指令代码域[27:20],除指令编码外、还包含几个很重要的指令特征位和可选后缀的编码
    • 地址基址Rn域[19:16],4位可编码R0-R15共16个寄存器
    • 目标或源寄存器Rd域[15:12],4位可编码R0-R15共16个寄存器
    • 地址偏移或操作寄存器、操作数域[11:0]

指令可选后缀

S 后缀

  • 含义:使用S后缀时,指令执行后程序状态寄存器的条件标志位将刷新;如:ADDS R3,R5,R8
  • 使用范围
    • 有些指令不需要加S后缀,在执行时同样可以刷新条件标志位。如:CMP, TEQ, TST等。
    • 有些指令不会引起条件标志位的变化,如:STR R5, [R7]
  • 在书写时,S后缀紧跟在指令助记符后面

!后缀

  • 含义:在指令的地址表达式中含有!后缀时,指令执行后,基址寄存器中的地址将发生变化(事先访问方式)

基址寄存器中的地址值 (指令执行后) =指令执行前的值+地址偏移量

  • 位置和范围
    • !后缀必须紧跟在表达地址的表达式后面,而地址表达式要有明确的地址偏移量
    • !后缀不能用在R15的后面
    • 当使用在单个地址寄存器后面时,必须确信这个寄存器有隐性的偏移量,如:STMDB R1!, {R3,R14}

B 后缀 / H 后缀

  • 含义:

    • B后缀的含义:指令所涉及的数据是一字节,不是一字或半字。
    • H后缀的含义:指令所涉及的数据是二字节,不是一字。
  • 位置

    • B后缀紧跟在指令助记符后面。
    • H后缀紧跟在指令助记符后面。

T 后缀

  • 含义:指令在特权模式下对存储器的访问,将被存储器看成是用户模式的访问。
  • 限制:
    • 一般只用在字传送和无符号字节传送中
    • 在用户模式下不可选用,选用是没有意义的
    • 不能与事先更新寻址一起使用

条件后缀

ARM微处理器编程|指令系统-算术指令_第1张图片

  • 被测试条件位有Z、C、N和V
  • 在汇编语言中,条件码助记符紧接在指令助记符后面,如果既选条件后缀也选S后缀,则书写中“S”排列在后面。
  • 条件后缀是要测试条件标志位,而S后缀是要刷新条件标志位
  • 条件后缀要测试的是指令执行前的标志位,而S后缀是依据指令执行的结果改变条件标志

指令类型

跳转指令

实现跳转的两种方法

  • 使用专门的跳转指令(短跳转,从当前指令向前或向后的32MB的地址空间的跳转)

    • B   跳转指令
    • BL 带返回的跳转指令(函数调用)
    • BX 带状态切换的跳转指令
    • BLX  带返回和状态切换的跳转指令(ARM7不支持)
  • 直接向程序计数器PC写入跳转地址值(长跳转,可以实现在4GB的地址空间中的任意跳转)

跳转指令的编码

ARM微处理器编程|指令系统-算术指令_第2张图片

  • 存储在跳转指令中的实际值是相对当前PC值的一个偏移量,而不是一个绝对地址
  • 处理器把偏移量(24 位有符号数)左移两位,进行符号扩展后再与PC相加。
  • 左移两位:机器字长32位,指令中给出的偏移量是按字(32位)寻址的,而PC寄存器的内容按字节(8位)寻址,也就是说假如给出的偏移量是0x0100,那么对应按字节寻址的地址就应该是0x0400,即按字寻址的偏移量的4倍,也就是左移2位,才能与PC内容相加。

B 指令

B{条件} 目标地址

  • B指令是最简单的跳转指令。一旦遇到一个 B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继续执行。

ARM微处理器编程|指令系统-算术指令_第3张图片

BL 指令

BL{条件} 目标地址

  • 该指令是实现子程序调用的一个基本而常用的手段:跳转之前,会在寄存器R14中保存PC的当前内容(下一条指令),因此,可以通过将R14(LR) 的内容重新加载到PC中,来返回到跳转指令之后的那个指令处执行。
    ARM微处理器编程|指令系统-算术指令_第4张图片

条件跳转

ARM微处理器编程|指令系统-算术指令_第5张图片

BX指令

BX{条件}

  • BX指令跳转到指令中所指定的目标地址,目标地址处的指令既可以是ARM指令,也可以是Thumb指令。
  • 目标地址处的指令类型由寄存器的bit[0]决定。

ARM微处理器编程|指令系统-算术指令_第6张图片

  • 伪代码:
    ARM微处理器编程|指令系统-算术指令_第7张图片

BLX 指令

BLX 目标地址

  • BLX 目标地址指令从ARM指令集跳转到指令中所指定的目标地址,并将处理器的工作状态由ARM状态切换到Thumb状态,该指令同时将PC的当前内容保存到寄存器R14中
  • 子程序的返回可以通过将寄存器R14值复制到PC中来完成。
  • 从ARM到Thumb的状态切换,并可以通过BX R14返回。

在这里插入图片描述

BLX{条件}

  • BLX{条件} 指令跳转到指令中所指定的目标地址,目标地址处的指令既可以是ARM指令,也可以是Thumb指令。目标地址处的指令类型由寄存器的bit[0]决定

在这里插入图片描述

子程序的返回方法

  • MOV PC, R14
  • BX R14
  • 当子程序入口中使用了STMFD R13!, {,R14}时,可以用指令LDMFD R13!, {,PC}返回

数据处理指令

ARM微处理器编程|指令系统-算术指令_第8张图片

<操作>{}{S} Rd, Rn, Operand2

  • 比较指令影响标志位,不指定Rd
  • 数据搬移不指定Rn

ARM微处理器编程|指令系统-算术指令_第9张图片

  • 第二个操作数通过桶型移位器送到ALU中。

ARM微处理器编程|指令系统-算术指令_第10张图片

数据搬移

MOV 指令

ARM微处理器编程|指令系统-算术指令_第11张图片

MOV{条件}{S} 目的寄存器,源操作数

  • MOV指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器。
  • 其中S选项决定指令的操作是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。
    • 当PC作为目标寄存器且指令中S位被置位时,指令在执行跳转操作的同时,将当前处理器模式的SPSR内容复制到CPSR中。
    • MOVS PC, LR可以实现从某些异常中断中返回

ARM微处理器编程|指令系统-算术指令_第12张图片

  • 指令示例
MOV   R1,R0 ;将寄存器R0的值传送到寄存器R1
MOV   PC,R14 ;将寄存器R14的值传送到PC,常用于子程序返回
MOV   R1,R0,LSL#3 ;将寄存器R0的值左移3位后传送到R1
MOV   R1,#123 ;将立即数123传送到R1

MVN 指令

MVN{条件}{S} 目的寄存器,源操作数

  • MVN指令可完成从另一个寄存器、被移位的寄存器、或将一个立即数加载到目的寄存器。
  • 与MOV指令不同之处是在传送之前按位被取反了,即把一个被取反的值传送到目的寄存器中。
    在这里插入图片描述

比较指令

CMP 指令

CMP{条件} 操作数1,操作数2

  • CMP指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新CPSR中条件标志位的值
  • 该指令进行一次减法运算,但不存储结果,只更改条件标志位。

ARM微处理器编程|指令系统-算术指令_第13张图片

  • 指令示例
CMP   R1,R0  ;将寄存器R1的值与寄存器R0的值相减,并根据结果设置CPSR的标志位
CMP   R1,#100  ;将寄存器R1的值与立即数100相减,并根据结果设置CPSR的标志位

CMN 指令

CMN{条件} 操作数1,操作数2

  • CMN指令用于把一个寄存器的内容和另一个寄存器的内容或立即数取反后进行比较,同时更新CPSR中条件标志位的值。
  • 该指令实际完成操作数1和操作数2相加,并根据结果更改条件标志位。
    ARM微处理器编程|指令系统-算术指令_第14张图片
  • 指令示例
CMN   R1,R0 ;将寄存器R1的值与寄存器R0的值相			加,并根据结果设置CPSR的标志位
CMN   R1,#100  ;将寄存器R1的值与立即数100相			加,并根据结果设置CPSR的标志位

TST 指令

TST{条件} 操作数1,操作数2

  • TST指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位与运算,并根据运算结果更新CPSR中条件标志位的值。
  • 操作数1是要测试的数据,而操作数2是一个位掩码,该指令一般用来检测是否设置了特定的位。TST指令用于测试寄存器中某些位是1还是0

ARM微处理器编程|指令系统-算术指令_第15张图片

  • 指令示例
TST   R1,#%1 ;用于测试在寄存器R1中是否设置了最低			位(%表示二进制数)
TST   R1,#0xfe ;将寄存器R1的值与立即数0xfe按位			与,并根据结果设置CPSR的标志位

TEQ 指令

TEQ{条件} 操作数1,操作数2

  • TEQ指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位异或运算,并根据运算结果更新CPSR中条件标志位的值。
  • TEQ指令通常用于比较操作数1和操作数2是否相等
    ARM微处理器编程|指令系统-算术指令_第16张图片

算术指令

ADD 指令

ADD{条件}{S} 目的寄存器,操作数1,操作数2

  • ADD指令用于把两个操作数相加,并将结果存放到目的寄存器中。
  • 操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数
  • 指令示例
ADD    R0,R1,R2  ; R0 = R1 + R2
ADD    R0,R1,#256  ; R0 = R1 + 256
ADDS   R0,R2,R3,LSL#1  ; R0 = R2 + (R3 << 1)

ADC 指令

ADC{条件}{S} 目的寄存器,操作数1,操作数2

  • ADC指令用于把两个操作数相加,再加上CPSR中的C条件标志位的值,并将结果存放到目的寄存器中。
  • 它使用一个进位标志位,这样就可以做比32位大的数的加法,注意不要忘记设置S后缀来更改进位标志。
  • ADC指令和ADD指令联合使用可以实现64位、128位的加法操作

ARM微处理器编程|指令系统-算术指令_第17张图片

  • 以下指令序列完成两个128位数的加法,第一个数由高到低存放在寄存器R7~R4,第二个数由高到低存放在寄存器R11~R8,运算结果由高到低存放在寄存器R3~R0
ADDS   R0,R4,R8     ; 加低端的字
ADCS   R1,R5,R9     ; 加第二个字,带进位
ADCS   R2,R6,R10   ; 加第三个字,带进位
ADC     R3,R7,R11    ; 加第四个字,带进位

SUB 指令

SUB{条件}{S} 目的寄存器,操作数1,操作数2

  • SUB指令用于把操作数1减去操作数2,并将结果存放到目的寄存器中。
  • 该指令可用于有符号数或无符号数的减法运算。

ARM微处理器编程|指令系统-算术指令_第18张图片

  • 指令示例
SUB     R0,R1,R2   ; R0 = R1 - R2
SUB     R0,R1,#256   ; R0 = R1 - 256
SUBS   R0,R2,R3,LSL#1  ; R0 = R2 - (R3 << 1)

ARM微处理器编程|指令系统-算术指令_第19张图片

SBC 指令

SBC{条件}{S} 目的寄存器,操作数1,操作数2

  • SBC指令用于把操作数1减去操作数2,再减去CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。
  • 该指令使用进位标志来表示借位,这样就可以做大于32位的减法,注意不要忘记设置S后缀来更改进位标志。
  • SBC指令和SUB指令联合使用可以实现64位、128位的减法操作

ARM微处理器编程|指令系统-算术指令_第20张图片

  • 指令示例
SBC R0,R1,R2  ;R0 = R1 - R2 - !C,并根据结果设置CPSR的进位标志位

RSB 指令

RSB{条件}{S} 目的寄存器,操作数1,操作数2

  • RSB指令称为逆向减法指令,用于把操作数2减去操作数1,并将结果存放到目的寄存器中。
  • 该指令可用于有符号数或无符号数的减法运算。
  • 指令示例
RSB     R0,R1,R2  ; R0 = R2 – R1
RSB     R0,R1,#256  ; R0 = 256 – R1
RSBS   R0,R2,R3,LSL#1  ; R0 = (R3 << 1) - R2

ARM微处理器编程|指令系统-算术指令_第21张图片

RSC 指令

RSC{条件}{S} 目的寄存器,操作数1,操作数2

  • RSC指令用于把操作数2减去操作数1,再减去CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。
  • 该指令使用进位标志来表示借位,这样就可以做大于32位的减法,注意不要忘记设置S后缀来更改进位标志。
  • RSC指令和RSB指令联合使用可以实现64位、128位的减法操作
  • 指令示例
RSC   R0,R1,R2   ; R0 = R2 – R1 - !C

逻辑指令

AND 指令

AND{条件}{S} 目的寄存器,操作数1,操作数2

  • AND指令用于在两个操作数上进行逻辑与运算,并把结果放置到目的寄存器中。
  • 该指令常用于屏蔽操作数1的某些位。
  • 设置一个掩码值,AND指令可以提取寄存器中某些位的值

ARM微处理器编程|指令系统-算术指令_第22张图片

  • 指令示例
AND   R0,R0,#3   ; 该指令保持R0的0、1位,其余位				清零。

ORR 指令

ORR{条件}{S} 目的寄存器,操作数1,操作数2

  • ORR指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。
  • 该指令常用于设置操作数1的某些位。
  • 设置一个掩码值,ORR指令可以设置寄存器中某些位的值为1
  • 指令示例
ORR   R0,R0,#3 ; 该指令设置R0的0、1位,其余位保持不变。

在这里插入图片描述

EOR 指令

EOR{条件}{S} 目的寄存器,操作数1,操作数2

  • EOR指令用于在两个操作数上进行逻辑异或运算,并把结果放置到目的寄存器中。
  • 该指令常用于反转操作数1的某些位。
  • 设置一个掩码值,EOR指令可以将寄存器中某些位的值取反
  • 指令示例
EOR   R0,R0,#3   ; 该指令反转R0的0、1位,其余位保持不变。

BIC 指令

BIC{条件}{S} 目的寄存器,操作数1,操作数2

  • BIC指令用于清除操作数1的某些位,并把结果放置到目的寄存器中。
  • 操作数2为32位的掩码,如果在掩码中设置了某一位,则清除这一位,未设置的掩码位保持不变。
  • 设置一个掩码值,BIC指令可以将寄存器中某些位的值设置成0
  • 指令示例
BIC   R0,R0,#%1011  ; 该指令清除 R0 中的位 0、1、和3,其余的位保持不变。

在这里插入图片描述

乘法指令与乘加指令

  • ARM微处理器支持的乘法指令与乘加指令共有6条,可分为运算结果为32位和运算结果为64位两类,与前面的数据处理指令不同
    • 指令中的所有操作数、目的寄存器必须为通用寄存器,不能对操作数使用立即数或被移位的寄存器
    • 目的寄存器和操作数1必须是不同的寄存器。
  • 乘法指令与乘加指令共有以下6条
    • MUL 32位乘法指令
    • MLA 32位乘加指令
    • SMULL 64位有符号数乘法指令
    • SMLAL 64位有符号数乘加指令
    • UMULL 64位无符号数乘法指令
    • UMLAL 64位无符号数乘加指令

MUL 指令

MUL{条件}{S} 目的寄存器,操作数1,操作数2

  • MUL指令完成将操作数1与操作数2的乘法运算,并把结果放置到目的寄存器中,同时可以根据运算结果设置CPSR中相应的条件标志位。
    • 其中,操作数1和操作数2均为32位的有符号数或无符号数。
  • 结果仅保存了64位的低32位
  • 指令示例
MUL     R0,R1,R2 ;R0 = R1 × R2
MULS    R0,R1,R2 ;R0 = R1 × R2,同时设置CPSR中的相关条件标志位
  • 在早期的ARM版本中,如果Rd和Rm是同一寄存器,则该行为是不可预测的。(ARM Wiki和ARM官方文档)。
    ARM微处理器编程|指令系统-算术指令_第23张图片

MLA 指令

MLA{条件}{S} 目的寄存器, 操作数1,操作数2,操作数3

  • MLA指令完成将操作数1与操作数2的乘法运算,再将乘积加上操作数3,并把结果放置到目的寄存器中,同时可以根据运算结果设置CPSR中相应的条件标志位。
  • 其中,操作数1和操作数2均为32位的有符号数或无符号数。
  • 指令示例
MLA     R0,R1,R2,R3  ;R0 = R1 × R2 + R3
MLAS    R0,R1,R2,R3   ;R0 = R1 × R2 + R3,同时设置CPSR中的相关条件标志位

ARM微处理器编程|指令系统-算术指令_第24张图片

SMULL 指令

SMULL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2

  • SMULL指令完成将操作数1与操作数2的乘法运算,并把结果的低32位放置到目的寄存器Low中,结果的高32位放置到目的寄存器High中,同时可以根据运算结果设置CPSR中相应的条件标志位。
  • 其中,操作数1和操作数2均为32位的有符号数。
  • 指令示例
SMULL R0,R1,R2,R3  
				;R0 = (R2 × R3)的低32位
                ;R1 = (R2 × R3)的高32位 

SMLAL 指令

SMLAL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2

  • SMLAL指令完成将操作数1与操作数2的乘法运算,并把结果的低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,结果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,同时可以根据运算结果设置CPSR中相应的条件标志位。
  • 对于目的寄存器Low,在指令执行前存放64位加数的低32位,指令执行后存放结果的低32位。
  • 对于目的寄存器High,在指令执行前存放64位加数的高32位,指令执行后存放结果的高32位。
  • 其中,操作数1和操作数2均为32位的有符号数。
  • 指令示例
SMLAL R0,R1,R2,R3
				;R0 = (R2 × R3)的低32位 + R0
                ;R1 = (R2 × R3)的高32位 + R1 + C

UMULL 指令

UMULL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2

  • UMULL指令完成操作同SMULL
  • 其中,操作数1和操作数2均为32位的无符号数。

UMLAL 指令

UMLAL{条件}{S} 目的寄存器Low,目的寄存器低 High,操作数1,操作数2

  • UMLAL指令完成操作同SMLAL
  • 其中,操作数1和操作数2均为32位的无符号数。

你可能感兴趣的:(#,嵌入式开发,arm)