ARM微处理器的指令系统

ARM微处理器编程模型与linux驱动开发 它是一个独立的黑盒子,使某个特定的 硬件可以响应一个定义良好的内部编程接口,同时完成隐藏设备的工作。在顶层的Makefile会读取config文件(默认的是.config), 根据.config文件的配置选项编译内核,顶层Makefile会递归的遍历每一个子目录下的Makefile文件(编译各个目录下的的目标文件)抢占优先级的级别高于响应优先级。0:用户模式,1:快速中断模式,2:中断模式,3:管理模式,4:中止模式,5:未定义模式,6:系统模式,7:Monnitor模式,8:hypervisor模式。 阅读详情


   介绍 ARM指令集、Thumb指令集,以及各类指令对应的寻址方式,通过对本章的阅读,希望读者能了解ARM微处理器所支持的指令集及具体的使用方法。

本章的主要内容有:

-   ARM指令集、Thumb指令集概述。

-   ARM指令集的分类与具体应用。

-   Thumb指令集简介及应用场合。

3.1  ARM微处理器的指令集概述

3.1.1  ARM微处理器的指令的分类与格式

ARM微处理器的指令集是加载/存储型的,也即指令集仅能处理寄存器中的数据,而且处理结果都要放回寄存器中,而对系统存储器的访问则需要通过专门的加载/存储指令来完成。

ARM微处理器的指令集可以分为跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令和异常产生指令六大类,具体的指令及功能如表3-1所示(表中指令为基本ARM指令,不包括派生的ARM指令)。

   表3-1   ARM指令及功能描述

助记符

指令功能描述

ADC

带进位加法指令

ADD

加法指令

AND

逻辑与指令

B

跳转指令

BIC

位清零指令

BL

带返回的跳转指令

BLX

带返回和状态切换的跳转指令

BX

带状态切换的跳转指令

CDP

协处理器数据操作指令

CMN

比较反值指令

CMP

比较指令

EOR

异或指令

LDC

存储器到协处理器的数据传输指令

LDM

加载多个寄存器指令

LDR

存储器到寄存器的数据传输指令

MCR

从ARM寄存器到协处理器寄存器的数据传输指令

MLA

乘加运算指令

MOV

数据传送指令

MRC

从协处理器寄存器到ARM寄存器的数据传输指令

MRS

传送CPSR或SPSR的内容到通用寄存器指令

MSR

传送通用寄存器到CPSR或SPSR的指令

MUL

32位乘法指令

MLA

32位乘加指令

MVN

数据取反传送指令

ORR

逻辑或指令

RSB

逆向减法指令

RSC

带借位的逆向减法指令

SBC

带借位减法指令

STC

协处理器寄存器写入存储器指令

STM

批量内存字写入指令

STR

寄存器到存储器的数据传输指令

SUB

减法指令

SWI

软件中断指令

SWP

交换指令

TEQ

相等测试指令

TST

位测试指令

    3.1.2  指令的条件域

当处理器工作在ARM状态时,几乎所有的指令均根据CPSR中条件码的状态和指令的条件域有条件的执行。当指令的执行条件满足时,指令被执行,否则指令被忽略。

每一条ARM指令包含4位的条件码,位于指令的最高4位[31:28]。条件码共有16种,每种条件码可用两个字符表示,这两个字符可以添加在指令助记符的后面和指令同时使用。例如,跳转指令B可以加上后缀EQ变为BEQ表示“相等则跳转”,即当CPSR中的Z标志置位时发生跳转。

在16种条件标志码中,只有15种可以使用,如表3-2所示,第16种(1111)为系统保留,暂时不能使用。

   表3-2       指令的条件码

条件码

助记符后缀

标 志

含 义

0000

EQ

Z置位

相等

0001

NE

Z清零

不相等

0010

CS

C置位

无符号数大于或等于

0011

CC

C清零

无符号数小于

0100

MI

N置位

负数

0101

PL

N清零

正数或零

0110

VS

V置位

溢出

0111

VC

V清零

未溢出

1000

HI

C置位Z清零

无符号数大于

1001

LS

C清零Z置位

无符号数小于或等于

1010

GE

N等于V

带符号数大于或等于

1011

LT

N不等于V

带符号数小于

1100

GT

Z清零且(N等于V)

带符号数大于

1101

LE

Z置位或(N不等于V)

带符号数小于或等于

1110

AL

忽略

无条件执行

  3.2  ARM指令的寻址方式

       所谓寻址方式就是处理器根据指令中给出的地址信息来寻找物理地址的方式。目前ARM指令系统支持如下几种常见的寻址方式。

   3.2.1  立即寻址

       立即寻址也叫立即数寻址,这是一种特殊的寻址方式,操作数本身就在指令中给出,只要取出指令也就取到了操作数。这个操作数被称为立即数,对应的寻址方式也就叫做立即寻址。例如以下指令:

ADD R0,R0,#1         ;R0← R0+1

ADD R0,R0,#0x3f       ;R0← R0+0x3f

       在以上两条指令中,第二个源操作数即为立即数,要求以“#”为前缀,对于以十六进制表示的立即数,还要求在“#”后加上“0x”或“&”。

    3.2.2  寄存器寻址

       寄存器寻址就是利用寄存器中的数值作为操作数,这种寻址方式是各类微处理器经常采用的一种方式,也是一种执行效率较高的寻址方式。以下指令:

ADD R0,R1,R2          ;R0← R1+R2

       该指令的执行效果是将寄存器R1和R2的内容相加,其结果存放在寄存器R0中。

  3.2.2  寄存器间接寻址

       寄存器间接寻址就是以寄存器中的值作为操作数的地址,而操作数本身存放在存储器中。例如以下指令:

ADD R0,R1,[R2]        ;R0← R1+[R2]

LDR  R0,[R1]              ;R0← [R1]

STR  R0,[R1]              ;[R1]←R0

    在第一条指令中,以寄存器R2的值作为操作数的地址,在存储器中取得一个操作数后与R1相加,结果存入寄存器R0中。

    第二条指令将以R1的值为地址的存储器中的数据传送到R0中。

    第三条指令将R0的值传送到以R1的值为地址的存储器中。

      3.2.3  基址变址寻址

       基址变址寻址就是将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址。变址寻址方式常用于访问某基地址附近的地址单元。采用变址寻址方式的指令常见有以下几种形式,如下所示:

LDR R0,[R1,#4]           ;R0← [R1+4]

LDR R0,[R1,#4]!         ;R0← [R1+4]、R1←R1+4

LDR R0,[R1] ,#4          ;R0← [R1]、R1←R1+4

LDR R0,[R1,R2]            ;R0← [R1+R2]

      在第一条指令中,将寄存器R1的内容加上4形成操作数的有效地址,从而取得操作数存入寄存器R0中。

      在第二条指令中,将寄存器R1的内容加上4形成操作数的有效地址,从而取得操作数存入寄存器R0中,然后,R1的内容自增4个字节。

      在第三条指令中,以寄存器R1的内容作为操作数的有效地址,从而取得操作数存入寄存器R0中,然后,R1的内容自增4个字节。

      在第四条指令中,将寄存器R1的内容加上寄存器R2的内容形成操作数的有效地址,从而取得操作数存入寄存器R0中。

      3.2.4  多寄存器寻址

采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。这种寻址方式可以用一条指令完成传送最多16个通用寄存器的值。以下指令:

LDMIA R0,{R1,R2,R3,R4}       ;R1← [R0]

                               ;R2← [R0+4]

                                    ;R3← [R0+8]

                                    ;R4← [R0+12]

     该指令的后缀IA表示在每次执行完加载/存储操作后,R0按字长度增加,因此,指令可将连续存储单元的值传送到R1~R4。

      3.2.5  相对寻址

     与基址变址寻址方式相类似,相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。以下程序段完成子程序的调用和返回,跳转指令BL采用了相对寻址方式:

BL NEXT                   ;跳转到子程序NEXT处执行

……                        

    NEXT

……                             

MOV  PC,LR                     ;从子程序返回

      3.2.6  堆栈寻址

     堆栈是一种数据结构,按先进后出(First In Last Out,FILO)的方式工作,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。

     当堆栈指针指向最后压入堆栈的数据时,称为满堆栈(Full Stack),而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈(Empty Stack)。

     同时,根据堆栈的生成方式,又可以分为递增堆栈(Ascending  Stack)和递减堆栈(Decending Stack),当堆栈由低地址向高地址生成时,称为递增堆栈,当堆栈由高地址向低地址生成时,称为递减堆栈。这样就有四种类型的堆栈工作方式,ARM微处理器支持这四种类型的堆栈工作方式,即:

     -    满递增堆栈:堆栈指针指向最后压入的数据,且由低地址向高地址生成。

     -    满递减堆栈:堆栈指针指向最后压入的数据,且由高地址向低地址生成。

     -    空递增堆栈:堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成。

     -    空递减堆栈:堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生成。

3.3  ARM指令集

     本节对ARM指令集的六大类指令进行详细的描述。

      3.3.1  跳转指令

       跳转指令用于实现程序流程的跳转,在ARM程序中有两种方法可以实现程序流程的跳转:

 —        使用专门的跳转指令。

 —        直接向程序计数器PC写入跳转地址值。

      通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转,在跳转之前结合使用

     MOV   LR,PC

      等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性地址空间的子程序调用。

       ARM指令集中的跳转指令可以完成从当前指令向前或向后的32MB的地址空间的跳转,包括以下4条指令:

      —    B     跳转指令

 —        BL  带返回的跳转指令

 —        BLX 带返回和状态切换的跳转指令

 —        BX  带状态切换的跳转指令

      1、 B指令

 B指令的格式为:

 B{条件}  目标地址

  B指令是最简单的跳转指令。一旦遇到一个 B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继续执行。注意存储在跳转指令中的实际值是相对当前PC值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。它是 24 位有符号数,左移两位后有符号扩展为 32 位,表示的有效偏移为 26 位(前后32MB的地址空间)。以下指令:

     B     Label       ;程序无条件跳转到标号Label处执行

     CMP   R1,#0     ;当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label处执行

     BEQ   Label      

     2、 BL指令

 BL指令的格式为:

 BL{条件} 目标地址

 BL 是另一个跳转指令,但跳转之前,会在寄存器R14中保存PC的当前内容,因此,可以通过将R14 的内容重新加载到PC中,来返回到跳转指令之后的那个指令处执行。该指令是实现子程序调用的一个基本但常用的手段。以下指令:

    BL    Label       ;当程序无条件跳转到标号Label处执行时,同时将当前的PC值保存到R14中

     3、 BLX指令

 BLX指令的格式为:

 BLX  目标地址

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

    4、 BX指令

BX指令的格式为:

BX{条件}  目标地址

BX指令跳转到指令中所指定的目标地址,目标地址处的指令既可以是ARM指令,也可以是Thumb指令。

    3.3.2  数据处理指令

数据处理指令可分为数据传送指令、算术逻辑运算指令和比较指令等。

数据传送指令用于在寄存器和存储器之间进行数据的双向传输。

算术逻辑运算指令完成常用的算术与逻辑的运算,该类指令不但将运算结果保存在目的寄存器中,同时更新CPSR中的相应条件标志位。

比较指令不保存运算结果,只更新 CPSR中相应的条件标志位。

数据处理指令包括:

    —  MOV 数据传送指令

    —  MVN 数据取反传送指令

    —  CMP 比较指令

    —  CMN 反值比较指令

    —  TST 位测试指令

    —  TEQ 相等测试指令

    —  ADD 加法指令

    —  ADC 带进位加法指令

    —  SUB 减法指令

    —  SBC 带借位减法指令

    —  RSB 逆向减法指令

    —  RSC 带借位的逆向减法指令

    —  AND 逻辑与指令

    —  ORR 逻辑或指令

    —  EOR 逻辑异或指令

    —  BIC 位清除指令

    1、 MOV指令

MOV指令的格式为:

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

MOV指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器。其中S选项决定指令的操作是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。

指令示例:

    MOV   R1,R0         ;将寄存器R0的值传送到寄存器R1

    MOV   PC,R14        ;将寄存器R14的值传送到PC,常用于子程序返回

    MOV   R1,R0,LSL#3   ;将寄存器R0的值左移3位后传送到R1

    2、 MVN指令

MVN指令的格式为:

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

MVN指令可完成从另一个寄存器、被移位的寄存器、或将一个立即数加载到目的寄存器。与MOV指令不同之处是在传送之前按位被取反了,即把一个被取反的值传送到目的寄存器中。其中 S决定指令的操作是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。

指令示例:

MVN   R0,#0         ;将立即数0取反传送到寄存器R0中,完成后R0=-1

    3、 CMP指令

CMP指令的格式为:

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

CMP指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新 CPSR中条件标志位的值。该指令进行一次减法运算,但不存储结果,只更改条件标志位。标志位表示的是操作数1与操作数2的关系(大、小、相等),例如,当操作数1大于操作操作数2,则此后的有GT 后缀的指令将可以执行。

指令示例:

    CMP   R1,R0         ;将寄存器R1的值与寄存器R0的值相减,并根据结果设置CPSR的标志位

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

    4、 CMN指令

CMN指令的格式为:

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

CMN指令用于把一个寄存器的内容和另一个寄存器的内容或立即数取反后进行比较,同时更新 CPSR中条件标志位的值。该指令实际完成操作数1和操作数2相加,并根据结果更改条件标志位。

指令示例:

     CMN  R1,R0         ;将寄存器R1的值与寄存器R0的值相加,并根据结果设置CPSR的标志位

     CMN  R1,#100       ;将寄存器R1的值与立即数100相加,并根据结果设置CPSR的标志位

    5、 TST指令

TST指令的格式为:

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

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

指令示例:

    TST   R1,#%1        ;用于测试在寄存器R1中是否设置了最低位(%表示二进制数)

    TST   R1,#0xffe      ;将寄存器R1的值与立即数0xffe按位与,并根据结果设置CPSR的标志位

    6、 TEQ指令

TEQ指令的格式为:

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

TEQ指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的异或运算,并根据运算结果更新CPSR中条件标志位的值。该指令通常用于比较操作数1和操作数2是否相等。

指令示例:

TEQ   R1,R2      ;将寄存器R1的值与寄存器R2的值按位异或,并根据结果设置CPSR的标志位

    7、 ADD指令

ADD指令的格式为:

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

ADD指令用于把两个操作数相加,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。

指令示例:

    ADD   R0,R1,R2               ; R0 = R1 + R2

    ADD   R0,R1,#256             ; R0 = R1 + 256

    ADD   R0,R2,R3,LSL#1        ; R0 = R2 + (R3<< 1)

    8、 ADC指令

ADC指令的格式为:

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

ADC指令用于把两个操作数相加,再加上 CPSR中的C条件标志位的值,并将结果存放到目的寄存器中。它使用一个进位标志位,这样就可以做比32位大的数的加法,注意不要忘记设置S后缀来更改进位标志。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。

以下指令序列完成两个 128位数的加法,第一个数由高到低存放在寄存器R7~R4,第二个数由高到低存放在寄存器R11~R8,运算结果由高到低存放在寄存器R3~R0:

    ADDS R0,R4,R8            ; 加低端的字

    ADCS R1,R5,R9           ; 加第二个字,带进位

    ADCS R2,R6,R10          ; 加第三个字,带进位

    ADC   R3,R7,R11          ; 加第四个字,带进位

    9、 SUB指令

SUB指令的格式为:

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

SUB指令用于把操作数1减去操作数2,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令可用于有符号数或无符号数的减法运算。

指令示例:

    SUB   R0,R1,R2               ; R0 = R1 - R2

    SUB   R0,R1,#256             ; R0 = R1 - 256

    SUB   R0,R2,R3,LSL#1        ; R0 = R2 - (R3<< 1)

    10、SBC指令

SBC指令的格式为:

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

SBC指令用于把操作数1减去操作数2,再减去 CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令使用进位标志来表示借位,这样就可以做大于32位的减法,注意不要忘记设置 S后缀来更改进位标志。该指令可用于有符号数或无符号数的减法运算。

指令示例:

    SUBS R0,R1,R2               ; R0 = R1 - R2 - !C,并根据结果设置CPSR的进位标志位

    11、RSB指令

RSB指令的格式为:

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

RSB指令称为逆向减法指令,用于把操作数2减去操作数1,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令可用于有符号数或无符号数的减法运算。

指令示例:

    RSB   R0,R1,R2               ; R0 = R2 – R1

    RSB   R0,R1,#256             ; R0 = 256 – R1

    RSB   R0,R2,R3,LSL#1        ; R0 = (R3 << 1)- R2

    12、RSC指令

RSC指令的格式为:

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

RSC指令用于把操作数2减去操作数1,再减去 CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令使用进位标志来表示借位,这样就可以做大于32位的减法,注意不要忘记设置 S后缀来更改进位标志。该指令可用于有符号数或无符号数的减法运算。

指令示例:

RSC   R0,R1,R2               ; R0 = R2 – R1 - !C

    13、AND指令

AND指令的格式为:

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

AND指令用于在两个操作数上进行逻辑与运算,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于屏蔽操作数1的某些位。

指令示例:

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

    14、ORR指令

ORR指令的格式为:

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

ORR指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于设置操作数1的某些位。

指令示例:

    ORR   R0,R0,#3              ; 该指令设置R0的0、1位,其余位保持不变。

    15、EOR指令

EOR指令的格式为:

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

EOR指令用于在两个操作数上进行逻辑异或运算,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于反转操作数1的某些位。

指令示例:

    EOR   R0,R0,#3              ; 该指令反转R0的0、1位,其余位保持不变。

    16、BIC指令

BIC指令的格式为:

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

BIC指令用于清除操作数1的某些位,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。操作数2为32位的掩码,如果在掩码中设置了某一位,则清除这一位。未设置的掩码位保持不变。

指令示例:

    BIC   R0,R0,#%1011          ; 该指令清除 R0 中的位 0、1、和 3,其余的位保持不变。

    3.3.3  乘法指令与乘加指令

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

    乘法指令与乘加指令共有以下6条:

    — MUL     32位乘法指令

—       MLA     32位乘加指令

—       SMULL   64位有符号数乘法指令

—       SMLAL   64位有符号数乘加指令

—       UMULL   64位无符号数乘法指令

—       UMLAL   64位无符号数乘加指令

   1、 MUL指令

MUL指令的格式为:

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

MUL指令完成将操作数1与操作数2的乘法运算,并把结果放置到目的寄存器中,同时可以根据运算结果设置CPSR中相应的条件标志位。其中,操作数1和操作数2均为32位的有符号数或无符号数。

指令示例:

    MUL   R0,R1,R2       ;R0 = R1 × R2

    MULS  R0,R1,R2       ;R0 = R1 × R2,同时设置CPSR中的相关条件标志位

    2、 MLA指令

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中的相关条件标志位

    3、 SMULL指令

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位

    4、 SMLAL指令

SMLAL指令的格式为:

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

SMLAL指令完成将操作数1与操作数2的乘法运算,并把结果的低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,结果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,同时可以根据运算结果设置CPSR中相应的条件标志位。其中,操作数1和操作数2均为32位的有符号数。

对于目的寄存器 Low,在指令执行前存放64位加数的低32位,指令执行后存放结果的低32位。

对于目的寄存器 High,在指令执行前存放64位加数的高32位,指令执行后存放结果的高32位。

指令示例:

    SMLAL R0,R1,R2,R3       ;R0 = (R2 × R3)的低32位 + R0

                         ;R1 = (R2 × R3)的高32位 + R1

    5、 UMULL指令

UMULL指令的格式为:

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

UMULL指令完成将操作数1与操作数2的乘法运算,并把结果的低32位放置到目的寄存器Low中,结果的高32位放置到目的寄存器High中,同时可以根据运算结果设置CPSR中相应的条件标志位。其中,操作数1和操作数2均为32位的无符号数。

指令示例:

UMULL R0,R1,R2,R3       ;R0 = (R2 × R3)的低32位

                         ;R1 = (R2 × R3)的高32位

    6、 UMLAL指令

UMLAL指令的格式为:

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

UMLAL指令完成将操作数1与操作数2的乘法运算,并把结果的低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,结果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,同时可以根据运算结果设置CPSR中相应的条件标志位。其中,操作数1和操作数2均为32位的无符号数。

对于目的寄存器 Low,在指令执行前存放64位加数的低32位,指令执行后存放结果的低32位。

对于目的寄存器 High,在指令执行前存放64位加数的高32位,指令执行后存放结果的高32位。

指令示例:

     UMLAL R0,R1,R2,R3       ;R0 = (R2 × R3)的低32位 + R0

                         ;R1 = (R2 × R3)的高32位 + R1

     3.3.4  程序状态寄存器访问指令

ARM微处理器支持程序状态寄存器访问指令,用于在程序状态寄存器和通用寄存器之间传送数据,程序状态寄存器访问指令包括以下两条:

    —  MRS 程序状态寄存器到通用寄存器的数据传送指令

—       MSR 通用寄存器到程序状态寄存器的数据传送指令

    1、 MRS指令

MRS指令的格式为:

MRS{条件}    通用寄存器,程序状态寄存器(CPSR或SPSR)

MRS指令用于将程序状态寄存器的内容传送到通用寄存器中。该指令一般用在以下几种情况:

- 当需要改变程序状态寄存器的内容时,可用MRS将程序状态寄存器的内容读入通用寄存器,修改后再写回程序状态寄存器。

-  当在异常处理或进程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。

指令示例:

    MRS   R0,CPSR       ;传送CPSR的内容到R0

    MRS   R0,SPSR       ;传送SPSR的内容到R0

    2、 MSR指令

MSR指令的格式为:

MSR{条件}    程序状态寄存器(CPSR或SPSR)_<域>,操作数

MSR指令用于将操作数的内容传送到程序状态寄存器的特定域中。其中,操作数可以为通用寄存器或立即数。<域>用于设置程序状态寄存器中需要操作的位,32位的程序状态寄存器可分为4个域:

位 [31:24]为条件标志位域,用f表示;

位 [23:16]为状态位域,用s表示;

位 [15:8]为扩展位域,用x表示;

位 [7:0]为控制位域,用c表示;

该指令通常用于恢复或改变程序状态寄存器的内容,在使用时,一般要在 MSR指令中指明将要操作的域。

指令示例:

    MSR   CPSR,R0        ;传送R0的内容到CPSR

    MSR   SPSR,R0        ;传送R0的内容到SPSR

    MSR   CPSR_c,R0      ;传送R0的内容到SPSR,但仅仅修改CPSR中的控制位域

     3.3.5  加载/存储指令

ARM微处理器支持加载/存储指令用于在寄存器和存储器之间传送数据,加载指令用于将存储器中的数据传送到寄存器,存储指令则完成相反的操作。常用的加载存储指令如下:

    — LDR     字数据加载指令

—       LDRB    字节数据加载指令

    — LDRH    半字数据加载指令

    — STR     字数据存储指令

—       STRB    字节数据存储指令

    — STRH    半字数据存储指令

    1、LDR指令

LDR指令的格式为:

LDR{条件} 目的寄存器,<存储器地址>

LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中。该指令通常用于从存储器中读取32位的字数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。该指令在程序设计中比较常用,且寻址方式灵活多样,请读者认真掌握。

指令示例:

    LDR   R0,[R1]                 ;将存储器地址为R1的字数据读入寄存器R0。

    LDR   R0,[R1,R2]             ;将存储器地址为R1+R2的字数据读入寄存器R0。

    LDR   R0,[R1,#8]             ;将存储器地址为R1+8的字数据读入寄存器R0。

LDR   R0,[R1,R2] !          ;将存储器地址为R1+R2的字数据读入寄存器R0,并将新地址R1+R2写入R1。

    LDR   R0,[R1,#8] !         ;将存储器地址为R1+8的字数据读入寄存器R0,并将新地址R1+8写入R1。

    LDR   R0,[R1],R2              ;将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2写入R1。

    LDR   R0,[R1,R2,LSL#2]!   ;将存储器地址为R1+R2×4的字数据读入寄存器R0,并将新地址R1+R2×4写入R1。

    LDR   R0,[R1],R2,LSL#2     ;将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2×4写入R1。

    2、LDRB指令

LDRB指令的格式为:

LDR{条件}B 目的寄存器,<存储器地址>

LDRB指令用于从存储器中将一个8位的字节数据传送到目的寄存器中,同时将寄存器的高24位清零。该指令通常用于从存储器中读取8位的字节数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。

指令示例:

    LDRB R0,[R1]        ;将存储器地址为R1的字节数据读入寄存器R0,并将R0的高24位清零。

    LDRB R0,[R1,#8]    ;将存储器地址为R1+8的字节数据读入寄存器R0,并将R0的高24位清零。

    3、LDRH指令

LDRH指令的格式为:

LDR{条件}H 目的寄存器,<存储器地址>

LDRH指令用于从存储器中将一个16位的半字数据传送到目的寄存器中,同时将寄存器的高16位清零。该指令通常用于从存储器中读取16位的半字数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。

指令示例:

     LDRH R0,[R1]        ;将存储器地址为R1的半字数据读入寄存器R0,并将R0的高16位清零。

      LDRH R0,[R1,#8]    ;将存储器地址为R1+8的半字数据读入寄存器R0,并将R0的高16位清零。

     LDRH R0,[R1,R2]    ;将存储器地址为R1+R2的半字数据读入寄存器R0,并将R0的高16位清零。

     4、STR指令

STR指令的格式为:

STR{条件} 源寄存器,<存储器地址>

STR指令用于从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常用,且寻址方式灵活多样,使用方式可参考指令LDR。

指令示例:

    STR   R0,[R1],#8    ;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1。

    STR   R0,[R1,#8]    ;将R0中的字数据写入以R1+8为地址的存储器中。

    5、STRB指令

STRB指令的格式为:

STR{条件}B 源寄存器,<存储器地址>

STRB指令用于从源寄存器中将一个8位的字节数据传送到存储器中。该字节数据为源寄存器中的低8位。

指令示例:

    STRB R0,[R1]        ;将寄存器R0中的字节数据写入以R1为地址的存储器中。

    STRB R0,[R1,#8]    ;将寄存器R0中的字节数据写入以R1+8为地址的存储器中。

    6、STRH指令

STRH指令的格式为:

STR{条件}H 源寄存器,<存储器地址>

STRH指令用于从源寄存器中将一个16位的半字数据传送到存储器中。该半字数据为源寄存器中的低16位。

指令示例:

    STRH R0,[R1]        ;将寄存器R0中的半字数据写入以R1为地址的存储器中。

    STRH R0,[R1,#8]    ;将寄存器R0中的半字数据写入以R1+8为地址的存储器中。

    3.3.6  批量数据加载/存储指令

ARM微处理器所支持批量数据加载/存储指令可以一次在一片连续的存储器单元和多个寄存器之间传送数据,批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器,批量数据存储指令则完成相反的操作。常用的加载存储指令如下:

    — LDM     批量数据加载指令

—       STM     批量数据存储指令

    LDM(或STM)指令

LDM(或STM)指令的格式为:

LDM(或STM){条件}{类型} 基址寄存器{!},寄存器列表{ ∧}

LDM(或STM)指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多个寄存器之间传送数据,该指令的常见用途是将多个寄存器的内容入栈或出栈。其中,{类型}为以下几种情况:

IA   每次传送后地址加1;

IB   每次传送前地址加1;

DA   每次传送后地址减1;

DB   每次传送前地址减1;

FD   满递减堆栈;

ED   空递减堆栈;

FA   满递增堆栈;

EA   空递增堆栈;

{!}为可选后缀,若选用该后缀,则当数据传送完毕之后,将最后的地址写入基址寄存器,否则基址寄存器的内容不改变。

基址寄存器不允许为R15,寄存器列表可以为R0~R15的任意组合。

{ ∧ }为可选后缀,当指令为LDM且寄存器列表中包含 R15, 选用该后缀时表示:除了正常的数据传送之外,还将SPSR复制到CPSR。同时,该后缀还表示传入或传出的是用户模式下的寄存器,而不是当前模式下的寄存器。

指令示例:

STMFD  R13!,{R0,R4-R12,LR}     ;将寄存器列表中的寄存器(R0,R4到R12,LR)存入堆栈。

LDMFD  R13!,{R0,R4-R12,PC}     ;将堆栈内容恢复到寄存器(R0,R4到R12,LR)。

     3.3.7  数据交换指令

ARM微处理器所支持数据交换指令能在存储器和寄存器之间交换数据。数据交换指令有如下两条:

    — SWP     字数据交换指令

—       SWPB    字节数据交换指令

    1、SWP指令

SWP指令的格式为:

SWP{条件} 目的寄存器,源寄存器1,[源寄存器2]

SWP指令用于将源寄存器 2所指向的存储器中的字数据传送到目的寄存器中,同时将源寄存器 1中的字数据传送到源寄存器 2所指向的存储器中。显然,当源寄存器 1和目的寄存器为同一个寄存器时,指令交换该寄存器和存储器的内容。

指令示例:

    SWP   R0,R1,[R2]         ;将R2所指向的存储器中的字数据传送到R0,同时将R1中的字数

槽型光电开关传感器原理图设计,已量产(光电传感器) 在嵌入式设备的位置限位、物料计数等场景中,槽型光电开关是性价比极高的传感器方案 —— 它通过遮挡发射器与接收器之间的光路实现电平切换,电路简单且抗干扰性优于漫反射式光耦。今天分享一个实际项目中落地的槽型光电开关检测电路,从器件选型到逻辑设计都做了简化适配,适合小批量原型或低成本产品的需求。 阅读详情

相关推荐

Q&A | ZStack替代VMware实问实答

ZStack替代VMware实问实答

zstack_org的博客 1800

ARM常用汇编指令

1.数据传送指令 【MOV指令】:它的传送指令只能是把一个寄存器的值(要能用立即数表示)赋给另一个寄存器,或者将一个常量赋给寄存器,将后边的量赋给前边的量。 MOV指令的格式为:MOV{条件}{S}目的寄存器,源操作数 MOVr1,r0 ; 将寄存器r0的值传送到寄存器r1---->(r0 = r1) MOVpc,r14 ; 将寄存器r14的值传送到pc,常用于子程序返回---->(PC = r14) MOVr1,...

loveliu928的博客 4671

ARM64麒麟V10系统下PyTorch离线安装全攻略(附资源下载)

本文详细介绍了在ARM64架构的银河麒麟V10操作系统上,如何通过离线方式成功安装PyTorch深度学习框架。文章提供了从系统环境准备、依赖梳理、离线资源获取与验证,到分步安装、避坑指南及安装后验证的完整流程,并附有资源下载建议,旨在帮助开发者在国产化环境中高效部署AI开发平台。

metal的博客 746

【计算机三级嵌入式】考前学习笔记(二)——基本寻址方式、ARM指令集与伪指令介绍

备考计算机三级嵌入式时的一些笔记,本篇主要介绍ARM指令相关的内容,以及与指令运行相关的ARM寻址方式等内容

Vulcan_Q的博客 1415

保姆级教程:用CANoe的LIN Slave Conformance Tester搞定一致性测试(附LDF配置避坑点)

本文详细介绍了如何使用CANoe的LIN Slave Conformance Tester进行汽车电子LIN从节点一致性测试,包括测试环境搭建、LDF文件配置、多通道测试技巧及常见问题解决方案。通过实战案例和高级配置技巧,帮助工程师高效完成测试任务,确保LIN总线通信的可靠性。

weixin_30385925的博客 525

从手机到单片机:聊聊ARM Cortex家族那些事,A、R、M系列到底有啥不同?

本文深入解析ARM Cortex家族的A、R、M三大系列处理器,揭示它们在性能、实时响应和能效方面的核心差异。从智能手机到汽车电子和物联网设备,Cortex-A、R、M各司其职,分别应对复杂运算、实时控制和超低功耗场景。通过技术指标对比和典型应用案例,帮助开发者理解如何根据DMIPS/MHz等关键参数选择适合的处理器架构。

weixin_31574149的博客 350

第三章 微处理器的指令系统

第三章 微处理器的指令系统 3.1 8086/8088的寻址方式 3.1.1 数据寻址方式 立即寻址 将立即数传送到目标寄存器或存储器 操作数就在指令中(CPU直接从紧跟着指令代码的后续地址单元中取得该立即数) 不必执行总线周期 寄存器寻址 操作数放在CPU的寄存器中 对16位操作数,寄存器为8个16位通用寄存器(AX、BX、CX、DX、SP、BP、SI、DI) 对8位操作数,寄存器只能为AH、AL、BH、BL、CH、CL、DH、DL 操作数在CPU内部,不必执行总线周期 CS不能用MOV改变

weixin_46684748的博客 1764

3DGS实战笔记:从相机坐标系到屏幕像素,手把手推导高斯椭球的投影变换矩阵

本文详细解析了3D高斯散射(3DGS)技术中从相机坐标系到屏幕像素的几何变换过程,重点推导了高斯椭球的投影变换矩阵。通过视图变换、投影变换和视口变换的完整流程,结合雅可比矩阵处理协方差矩阵,实现了高效的三维重建与渲染。文章提供了Python代码示例,帮助开发者深入理解3DGS的核心几何变换机制。

weixin_28691741的博客 438

mov和ldr/str的区别

ARM是RISC(Reduced Instruction-Set Computer)结构,数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令。 比如想把数据从内存中某处读取到寄存器中,只能使用ldr 比如: ldr r0, 0x12345678 就是把0x12345678这个地址中的值存放到r0中。 而mov不能干这个活,mov只能在寄存器之间移动数据,或者把立

IC_SOC_ARM 2341

如何选择深度强化学习算法:MuZero/SAC/PPO/TD3/DDPG/DQN/等算法

如何选择深度强化学习算法:MuZero/SAC/PPO/TD3/DDPG/DQN/等算法

丨汀、的博客 5221

用 Python 和 XGBoost 进行疾病诊断预测

疾病诊断预测是医疗领域的重要研究方向,准确的疾病诊断预测可以帮助医生提前制定治疗方案,提高治疗效果,降低医疗成本。本文章的目的是介绍如何使用 Python 和 XGBoost 算法构建疾病诊断预测模型。范围涵盖了从数据预处理、模型训练到模型评估的整个流程,同时通过实际案例展示如何将该模型应用于疾病诊断预测中。本文首先介绍了疾病诊断预测的背景和 XGBoost 算法的核心概念,然后详细讲解了 XGBoost 算法的原理和具体操作步骤,包括 Python 代码实现。

AI Python 编程之道的博客 1064

ARM嵌入式实验ARM微处理器指令系统

实验三 ARM微处理器指令系统 一、实验目的 1. 掌握ARM微处理器指令集的书写格式; 2. 掌握ARM指令的寻址方式; 3. 掌握基本的ARM指令的用法; 二、实验内容 使用RealView MDK集成开发环境,编写汇编语言程序,使用基本的ARM指令以及不同寻址方式,通过查看结果掌握指令的功能。 三、实验要求 1. 能够熟悉使用RealView MDK集成开发环境建立工程和汇编源文件; 2. 能够编写完整的汇编语言程序段,并能够设置编译参数完成程序编译; 3. 能够正确书写基本的指令,能够查看寄存器

Happy_change的博客 990

Debezium报错处理系列之二十八: Expiring 1 record(s) for test-ts-0:120001 ms has passed since batch creation

Debezium报错处理系列之二十八: Expiring 1 record(s) for test-ts-0:120001 ms has passed since batch creation

zhengzaifeidelushang的博客 3290

ARM裸机开发篇2:ARM微处理器指令系统

目录 ARM微处理器指令系统 ARM处理器寻址方式 数据处理指令寻址方式 内存访问指令寻址方式 ARM处理器指令集 数据操作指令 乘法指令 Load/Store指令 跳转指令 状态操作指令 协处理器指令 异常产生指令 其他指令介绍 ARM 汇编实验 实验目的 实验原理 实验内容 实验步骤 实验现象 写在前面: 本文章为《ARM Cortex-A7裸机开发篇》系列中的一篇,全系列总计11篇。笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板)

华清远见IT实验室专栏 1115

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

ARM微处理器指令系统

1、ARM指令组成:要执行的指令,例如ADD、MOV、LDR...{}:指令执行的条件。例如:两个操作数相等指令执行或者一些其他的条件。{S}:1.我们运行结果是否要影响CPSR标志位2.当在异常处理是,如果要操作的是PC指针,那么当有S时,则会同时将SPSR寄存器得知恢复到CPSR中:目标寄存器,用于存放指令:操作数1,用于存放要操作的数据:操作数2,也是用于存放要操作的数据。

weixin_63481038的博客 413

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

arm微处理器指令系统_8086微处理器中的指令格式

arm微处理器指令系统For every instruction that is executed in the 8086 microprocessor, an instruction format is available that is the binary representation of that instruction. 对于在8086微处理器中执行的每条指令,都有一种指令格式 ,该...

cumt30111的博客 406

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

ARM微处理器的指令系统(转载)转自:http://www.360doc.com/content/10/1228/16/5294441_82052957.shtml

ARM微处理器的指令系统   介绍ARM指令集、Thumb指令集,以及各类指令对应的寻址方式,通过对本章的阅读,希望读者能了解ARM微处理器所支持的指令集及具体的使用方法。本章的主要内容有:-  ARM指令集、Thumb指令集概述。-  ARM指令集的分类与具体应用。-  Thumb指令集简介及应用场合。3.1  ARM微处理器的指令集概述3.1.1  ARM微处理器的指令的分类与格式ARM微处理

luoybtop的专栏 596

ARM开发:三 ARM微处理器的指令系统

3.1  ARM微处理器的指令集概述3.1.1  ARM微处理器的指令的分类与格式<br />ARM微处理器的指令集是加载/存储型的,也即指令集仅能处理寄存器中的数据,而且处理结果都要放回寄存器中,而对系统存储器的访问则需要通过专门的加载/存储指令来完成。<br />ARM微处理器的指令集可以分为跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令和异常产生指令六大类,具体的指令及功能如表3-1所示(表中指令为基本ARM指令,不包括派生的ARM指令)。<br />表3-1 

286

ARM应用系统开发详解:第3章 ARM微处理器的指令系统

3.1  ARM微处理器的指令集概述3.1.1  ARM微处理器的指令的分类与格式ARM微处理器的指令集是加载/存储型的,也即指令集仅能处理寄存器中的数据,而且处理结果都要放回寄存器中,而对系统存储器的访问则需要通过专门的加载/存储指令来完成。ARM微处理器的指令集可以分为跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令和异常产生指令六大类,具体的

Bekars涡轮增压的Blog ^_^ 4612

ARM开发:二 ARM微处理器的指令系统

2.1  ARM微处理器的工作状态<br />从编程的角度看,ARM微处理器的工作状态一般有两种,并可在两种状态之间切换:<br />-第一种为ARM状态,此时处理器执行32位的字对齐的ARM指令;<br />-第二种为Thumb状态,此时处理器执行16位的、半字对齐的Thumb指令。<br />当ARM微处理器执行32位的ARM指令集时,工作在ARM状态;当ARM微处理器执行16位的Thumb指令集时,工作在Thumb状态。在程序的执行过程中,微处理器可以随时在两种工作状态之间切换,并且,处理器工作状态的

292
上一篇: sata硬盘读写问题
linuxcc2011
博客等级 码龄16年 2粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值