您好,登录后才能下订单哦!
这篇文章给大家分享的是有关ARM体系结构与常用汇编指令是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
ARM(Advanced RISC Machines) ,既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。ARM 处理器是一种低功耗高性能的 32 位RISC 处理器,基于 ARM 的处理器以其高速度、低功耗等诸多优异的性能而得到非常广泛的应用。
ARM公司在经典处理器ARM11以后的产品改用Cortex命名,并分成A、R和M三类,其分别应用于不同的领域。Cortex系列属于ARMv7架构,其中“A”系列面向尖端的基于虚拟内存的操作系统和用户应用;“R”系列针对实时系统;“M”系列对微控制器。在ARM11推出前,其处理器比较:
ARM7 | ARM9 | ARM10 | ARM11 | |
---|---|---|---|---|
流水线 | 3级 | 5级 | 6级 | 8级 |
典型频率MHz | 80 | 150 | 260 | 335 |
功耗mW/MHz | 0.06 | 0.19(+cache) | 0.5 (+cache) | 0.4 (+cache) |
性能MIPS/MHz | 0.97 | 1.1 | 1.3 | 1.2 |
架构 | 冯*诺伊曼 | 哈佛 | 哈佛 | 哈佛 |
冯诺伊曼结构与哈佛结构的区别:
在TQ2440开发板上使用的是S3C2440芯片。这是一款基于ARM920T核心的微处理器芯片,采用哈佛结构使用5级指令流水线包括:取指、译码、执行、存储及写入。各步骤作用分别为:
(1)取指令(fetch):从存储器中取出指令,并将其放入指令流水线。
(2)译码(decode):指令被译码,从寄存器堆中读取寄存器操作数。在寄存器堆中有3个操作数读端口,因此,大多数ARM指令能在1个周期内读取其操作数。
(3)执行(execute):将其中1个操作数移位,并在ALU中产生结果。如果指令是Load或Store指令,则在ALU中计算存储器的地址。
(4)缓冲/数据(buffer/data):如果需要则访问数据存储器,否则ALU只是简单地缓冲1个时钟周期。
(5)回写(write-back):将指令的结果回写到寄存器堆,包括任何从寄存器读出的数据。
1.1ARM基本数据类型
ARM采用的是32位架构,基本数据类型有3种:Byte(字节), 8bit;Halfword(半字),16bit(半字必须2字节边界对齐);Word(字), 32bit(字必须于4字节边界对齐)。
长度为1个字的数据项占用一组4字节的位置,该位置开始于4的倍数的地址(地址最末两位为00)半字占有两个字节的位置,该位置开始于偶数字节地址(地址最末一位为0)。
1.2存储器大/小端
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。例如变量word a=0xf6734bcd,使用大/小端存储格式完全不一样。
1.3ARM编程模型
要想了解ARM920T为内核芯片的主要可以从几个方面入手:工作模式、ARM异常种类、寄存器组织、运行状态。
ARM920T是基于ARM V4T 架构,共有7种工作模式:
处理器 | 描述 |
---|---|
用户模式(usr) | ARM 处理器正常的程序执行状态。 |
快速中断模式(fiq) | 用于高速数据传输或通道处理。 |
外部中断模式(irq) | 用于通常的中断处理。 |
管理模式(svc) | 操作系统使用的保护模式。 |
数据访问终止模式(abt) | 当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护。 |
系统模式(sys) | 运行具有特权的操作系统任务。 |
未定义指令中止模式(und) | 当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真。 |
七种工作模式又可以从两个方面划分:特权模式与非特权模式;异常模式与非异常模式。
划分方式 | 说明 |
---|---|
特权模式与非特权模式 | 用户模式外的其他6种处理器模式称为特权模式(Privileged Modes)。在特权模式下,程序可以访问所有的系统资源,也可以任意地进行处理器模式切换,而用户模式不能直接切换到别的模式。 |
异常模式与非异常模式 | 除去用户模式和系统模式以外的 5 种又称为异常模式(ExceptionModes),常用于处理中断或异常,以及需要访问受保护的系统资源等情况。 |
在异常模式下,有着不同的异常,其对应关系为:
异常 | 向量表 | 模式 |
---|---|---|
复位(Reset) | 0x00 | 管理模式 |
未定义指令(Undefined Instruction) | 0x04 | 未定义指令中止模式 |
软中断(Software Interrupt) | 0x08 | 管理模式 |
指令预取异常(Prefetch Abrot) | 0x0C | 数据访问终止模式 |
数据异常(Data Abort) | 0x10 | 数据访问终止模式 |
保留(Reserved) | 0x14 | / |
中断(IRQ) | 0x18 | 数据访问终止模式 |
快速中断(FIQ) | 0x1C | 快速中断模式 |
ARM 处理器共有 37 个寄存器,被分为若干个组(BANK)。31 个通用寄存器,包括程序计数器(PC 指针),均为 32 位的寄存器;6 个状态寄存器,1个CPSR(Current Program Status Register,当前程序状态寄存器),5个SPSR(Saved Program Status Register,备份程序状态寄存器),用以标识 CPU 的工作状态及程序的运行状态,均为 32 位。ARM有7种不同的处理器模式,在每一种处理器模式中有一组相应的寄存器组。
在汇编语言中寄存器R0~R13为保存数据或地址值的通用寄存器。它们是完全通用的寄存器,不会被体系结构作为特殊用途,并且可用于任何使用通用寄存器的指令。这些通用寄存器根据其分组与否可分为以下2类。未分组寄存器(the Unbanked Register),包括R0~R7;分组寄存器(the Banked Register),包括R8~R14。
未分组寄存器没有被系统用于特殊的用途,任何可采用通用寄存器的应用场合都可以使用未分组寄存器。但由于其通用性,在异常中断所引起的处理器模式切换时,其使用的是相同的物理寄存器,所以也就很容易使寄存器中的数据被破坏。
分组寄存器根据处理器模式使用方法有所不同:
分组寄存器 | 说明 |
---|---|
R8~R12 | 每个寄存器对应两个不同的物理寄存器。一组用于除FIQ模式外的所有处理器模式,而另一组则专门用于FIQ模式。 |
R13和R14 | 每个寄存器对应6个不同的物理寄存器。其中的一个是用户模式和系统模式公用的,而另外5个分别用于5种异常模式。访问时需要指定它们的模式。名字形式:R13<mode>、R14<mode>。<mode>可以是以下几种模式之一:usr、svc、abt、und、irp及fiq。R13寄存器在ARM处理器中常用作堆栈指针,称为SP ;寄存器R14又被称为连接寄存器(Link Register,LR)。 |
程序计数器R15( PC),它指向正在取指的地址,在异常模式中,另外一个寄存器“ 程序状态备份寄存器( SPSR) ” 可以被访问。每种异常都有自己的SPSR,在进入异常时它保存CPSR的当前值,异常退出时可通过它恢复CPSR。该寄存器的位分配图为:
寄存器位 | 作用 |
---|---|
N位 | 符号位。如果结果为负数,则N = 1;如果结果为正数或0,则 N = 0 |
Z位 | 如果指令的结果为0,则置1(通常用来表示比较的结果为“相等”);否则置0 |
C位 | 表示运算的进位、借位等 |
V位 | 益出标志位 |
Q标志位 | 在带DSP指令扩展的ARM v5及更高版本中,bit[27]被指定用于指示增强的DAP指令是否发生了溢出,因此也就被称为Q标志位。同样,在SPSR中bit[27]也被称为Q标志位,用于在异常中断发生时保存和恢复CPSR中的Q标志位。在ARM v5以前的版本及ARM v5的非E系列处理器中,Q标志位没有被定义,属于待扩展的位。 |
I = 1 | IRQ被禁止 |
F = 1 | FIQ被禁止 |
T位 | 处理器的状态控制位。T = 0,处理器处于ARM状态(即正在执行32位的ARM指令)。T = 1,处理器处于Thumb状态(即正在执行16位的Thumb指令)。T位只有在T系列的ARM处理器上才有效,在非T系列的ARM版本中,T位将始终为0。 |
M[4∶0] | 作为位模式控制位,其具体控制模式可见下表。 |
ARM处理器的运行状态可以分为ARM与Thumb两种状态。其中ARM状态下PC值为字对齐(4字节),Thumb状态下PC值为半字对齐(2字节)。
在嵌入式开发中,汇编程序常常用于非常关键的地方,比如系统启动时的初始化,进出中断时的环境保存、恢复,对性能要求非常苛刻的函数等。ARM 微处理器的指令集主要有 6 大类:跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令、异常产生指令。
2.1跳转指令
跳转(B)和跳转连接(BL)指令是改变指令执行顺序的标准方式。ARM一般按照字地址顺序执行指令,需要时使用条件执行跳过某段指令。只要程序必须偏离顺序执行,就要使用控制流指令来修改程序计数器。主要有三条指令:
指令 | 语法格式 | 跳转范围 |
---|---|---|
跳转指令B及带连接的跳转指令BL | B{L}{<cond>} <target_address> | PC+-32MB |
BX带状态切换的跳转指令BX | BX{<cond>} <Rm> | 绝对地址4G |
BXL带状态切换的连接跳转指令BLX | BLX <target_add> | 绝对地址4G |
2.2数据处理指令
在了解ARM的数据处理指令之前要知道ARM的寻址方式,数据处理指令寻址方式可以分为3种:立即数寻址方式;寄存器寻址方式;寄存器移位寻址方式。其语法格式为:
<opcode> {<cond>} {S} <Rd>,<Rn>,<shifter_operand>,其中,<shifter_operand>有11种形式 。
数据指令寻址方式 | 指令 |
---|---|
立即数寻址 | 指令中的立即数是由一个8bit常数移动4bit偶数位得到的。 |
ADD R3,R3,#1 ;R3的值加1 | |
CMP R7,#1000 ;R7的值和1000比较 | |
BIC R9,R8,#0xFF00 ;将R8中8~15位清零,结果保存在R9中 | |
寄存器寻址方式 | 寄存器的值可以被直接用于数据操作指令,这种寻址方式是各类处理器经常采用的一种方式,也是一种执行效率较高的寻址方式。 |
ADD R4,R3,R2 ;R2加R3,结果送R4 | |
CMP R7,R8 ;比较R7和R8的值 | |
寄存器移位寻址方式 | 寄存器的值在被送到ALU之前,可以事先经过桶形移位寄存器的处理。预处理和移位发生在同一周期内,所以有效地使用移位寄存器,可以增加代码的执行效率。 |
MOV R1,R0,LSL #2 | |
RSB R9,R5,R5,LSL #1 |
内存访问指令寻址方式主要有以下几种。
寄存器指令寻址方式 | 含义 |
---|---|
寄存器间接寻址 | 指令中的地址码给出的是一个通用寄存器编号,所需要的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针,操作数存放在存储器中。 |
LDR R0,[R1] ; R0←[R1](将R1中的数值作为地址,取出此地址中的数据保存在R0中) STR R0,[R1] ; [R1] ←R0
寄存器指令寻址方式 | 含义 |
---|---|
变址寻址 | 将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址,变址寻址用于访问基址附近的存储单元,常用于查表,数组操作,功能部件寄存器访问等。 |
LDR R2,[R3,#4] ; R2←[R3 + 4](将R3中的数值加4作为地址,取出此地址的数值保存在R2 中) STR R1,[R0,#-2] ; [R0-2] ← R1
多寄存器寻址 | 含义 |
---|---|
变址寻址 | 采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送,这种寻址方式用一条指令最多可以完成16个寄存器值的传送。 |
LDMIA R0,{R1,R2,R3,R5} ; R1←[R0] (IA表示是后递增方式); R2←[R0 + 4] (IB表示是先递增方式) ; R3←[R0 + 8] (DA和DB表示后递减和先递减) ; R5←[R0 + 12]
多寄存器寻址 | 含义 |
---|---|
堆栈寻址 | 堆栈操作顺序分为“后进先出”和“先进后出”,堆栈寻址时隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存储单元就是堆栈的栈顶。 |
向上生长:向高地址方向生长,称为递增堆栈;向下生长:向低地址方向生长,称为递减堆栈。
堆栈指针指向最后压入的堆栈的有效数据项, 称为满堆栈(Full Stack);堆栈指针指向下一个要放入的空位置,称为空堆栈(
Empty Stack)。
堆栈工作方式 | 说明 |
---|---|
满递增堆栈 | 堆栈指针指向最后压入的数据,且由低地址向高地址生成。如指令LDMFA, STMFA 等。 |
满递减堆栈 | 堆栈指针指向最后压入的数据,且由高地址向低地址生成。如指令LDMFD, STMFD 等。 |
空递增堆栈 | 堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成。如指令LDMEA, STMEA 等。 |
空递减堆栈 | 堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生成。如指令LDMED, STMED 等。 |
数据操作指令是指对存放在寄存器中的数据进行操作的指令。包括:数据传送指令、 算术指令、 逻辑指令、 比较与测试指令及乘法指令。 如果在数据处理指令后使用S前缀,指令的执行结果将会影响CPSR中的标志位。
ARM乘法指令完成两个数据的乘法。两个32位二进制数相乘的结果是64位的积。
乘法指令 | 说明 |
---|---|
MUL指令 | MUL(Multiply)32位乘法指令将Rm和Rs中的值相乘,结果的最低32位保存到Rd中 |
MLA乘—累加指令 | MLA(Multiply Accumulate)32位乘—累加指令将Rm和Rs中的值相乘,再将乘积加上第3个操作数,结果的最低32位保存到Rd中。 |
UMULL指令 | UMULL(Unsigned Multiply Long)为64位无符号乘法指令。它将Rm和Rs中的值做无符号数相乘,结果的低32位保存到RsLo中,高32位保存到RdHi中。 |
UMLAL指令 | UMLAL(Unsigned Multiply Accumulate Long)为64位无符号长乘—累加指令。指令将Rm和Rs中的值做无符号数相乘,64位乘积与RdHi、RdLo相加,结果的低32位保存到RsLo中,高32位保存到RdHi中。 |
SMULL指令 | SMULL(Signed Multiply Long)为64位有符号长乘法指令。指令将Rm和Rs中的值做有符号数相乘,结果的低32位保存到RsLo中,高32位保存到RdHi中。 |
SMLAL指令 | SMLAL(Signed Multiply Accumulate Long)为64位有符号长乘—累加指令。指令将Rm和Rs中的值做有符号数相乘,64位乘积与RdHi、RdLo相加,结果的低32位保存到RsLo中,高32位保存到RdHi中。 |
2.3加载/存储指令
Load/Store内存访问指令在ARM寄存器和存储器之间传送数据。 ARM指令中有3种基本的数据传送指令。单寄存器Load/Store指令( Single Register);’多寄存器Load/Store内存访问指令;单寄存器交换指令( Single Register Swap)。
指令 | 说明 |
---|---|
单寄存器的Load/Store指令 | 用于把单一的数据传入或者传出一个寄存器。支持的数据类型有字节( 8位)、半字( 16位)和字( 32位)。 |
示例代码: LDR R2,[R5] ;将R5指向地址的字数据存入R2 STR R1,[R0,#0x04] ;将R1的数据存储到R0+0x04地址 LDRB R3,[R2],#-1 ;将R2指向地址的字节数据存入R3, R2=R2-1
指令 | 说明 |
---|---|
多寄存器的Load/Store内存访问指令 | 多寄存器的Load/Store内存访问指令也叫批量加载/存储指令,它可以实现在一组寄存器和一块连续的内存单元之间传送数据。 LDM用于加载多个寄存器, STM用于存储多个寄存器。 |
示例代码: LDR R0,=SrcData ;设置源数据地址 LDR R1,=DstData ;设置目标地址 LDMIA R0,{R2~R9} ;加载8字数据到寄存器R2~R9 STMIA R1,{R2~R9} ;存储寄存器R2~R9到目标地址
指令 | 说明 |
---|---|
单数据交换指令 | 交换指令是Load/Store指令的一种特例,它把一个寄存器单元的内容与寄存器内容交换。 |
2.4程序状态寄存器(PSR)处理指令
ARM指令集提供了两条指令,可直接控制程序状态寄存器。MRS指令用于把CPSR或SPSR的值传送到一个寄存器;MSR与之相反,把一个寄存器的内容传送到CPSR或SPSR。这两条指令相结合,可用于对CPSR和SPSR进行读/写操作。
( 1)MRS指令的语法格式: MRS{cond} Rd, PSR;Rd为目标寄存器, Rd不允许为程序计数器( PC)。 PSR为CPSR或SPSR。 指令举例: MRS R1,CPSR ;将CPSR状态寄存器读取,保存到R1中 MRS R2,SPSR ;将SPSR状态寄存器读取,保存到R1中
(2)MSR指令的语法格式 MSR{cond} PSR_field,#immed_8r 或MSR{cond} PSR_field,Rm <fields>设置状态寄存器中需要操作的位。状态寄存器的32位可以分为4个8位的域( field)。 bits[31: 24]为条件标志位域,用f表示; bits[23:16]为状态位域,用s表示; bits[15: 8]为扩展位域,用x表示; bits[7: 0]为控制位域,用c表示; immed_8r为要传送到状态寄存器指定域的立即数, 8位; Rm为要传送到状态寄存器指定域的数据源寄存器。 指令举例: MSR CPSR_c,#0xD3 ;CPSR[7:0]=0xD3,切换到管理模式 MSR CPSR_cxsf,R3 ;CPSR=R3
2.5协处理器指令
ARM协处理器指令可分为3类:协处理器数据操作, CDP;协处理器数据传送指令,包括LDC和STC;协处理器寄存器传送指令,包括MCR和MRC。
2.6异常产生指令
ARM指令集中提供了两条产生异常的指令,通过这两条指令可以用软件的方法实现异常。
为了使 C 语言程序和汇编程序之间能够互相调用,必须为子程序间的调用制定规则,在ARM 处理器中,这个规则被称为 ATPCS: ARM 程序和 Thumb 程序中子程序调用的规则。 基本的ATPCS 规则包括寄存器使用规则、数据栈使用规则、参数传递规则。
3.1、寄存器使用规则
ARM 处理器中有 r0~r15 共 16 个寄存器, 它们的用途有一些约定的习惯,并依具这些用途定义了别名,如下表所示:
寄存器 | 别名 | 使用规则 |
---|---|---|
Text | Text | Text |
r15 | pc | 程序计数器 |
r14 | lr | 连接寄存器 |
r13 | sp | 数据栈指针 |
r12 | ip | 子程序内部调用的 scratch 寄存器 |
r11 | v8 | ARM 状态局部变量寄存器 8 |
r10 | v7、 s1 | ARM 状态局部变量寄存器 7、在支持数据栈检查的 ATPCS 中为数据栈限制指针 |
r9 | v6、 sb | ARM 状态局部变量寄存器 6、在支持 RWPI 的 ATPCS 中为静态基址寄存器 |
r8 | v5 | ARM 状态局部变量寄存器 5 |
r7 | v4、 wr | ARM 状态局部变量寄存器 4、 Thumb 状态工作寄存器 |
r6 | v3 | ARM 状态局部变量寄存器 3 |
r5 | v2 | ARM 状态局部变量寄存器 2 |
r4 | v1 | ARM 状态局部变量寄存器 1 |
r3 | a4 | 参数/结果/scratch 寄存器 4 |
r2 | a3 | 参数/结果/scratch 寄存器 3 |
r1 | a2 | 参数/结果/scratch 寄存器 2 |
r0 | a1 | 参数/结果/scratch 寄存器 1 |
3.2、 数据栈使用规则
数据栈有两个增长方向:向内存地址减小的方向增长时,称为 DESCENDING 栈;向内地址增加的方向增长时,称为 ASCENDING 栈。
所谓数据栈的增长就是移动栈指针。当栈指针指向栈顶元素(最后一个入栈的数据)时,称为 FULL 栈;当栈指针指向栈顶元素(最后一个入栈的数据)相邻的一个空的数据单元时,称为 EMPTY 栈。
综合这两个特点, 数据栈可以分为以下 4 种:① FD Full Descending,满递减;② ED Empty Descending,空递减;③ FA Full Ascending,满递增;④ EA Empty Ascending,空递增。
ATPCS 规定数据栈为 FD 类型,并且对数据栈的操作是 8 字节对齐的。 使用 stmdb/ldmia批量内存访问指令来操作 FD 数据栈。
3.3、 参数传递规则
一般来说,当参数个数不超过 4 个时,使用 r0~r3 这 4 个寄存器来传递参数;如果参数个数超过 4 个,剩余的参数通过数据栈来传递。对于一般的返回结果, 通常使用 a0~a3 来传递。
感谢各位的阅读!关于“ARM体系结构与常用汇编指令是什么”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。