共计 8414 个字符,预计需要花费 22 分钟才能阅读完成。
这篇文章给大家分享的是有关 ARM 体系结构与常用汇编指令是什么的内容。丸趣 TV 小编觉得挺实用的,因此分享给大家做个参考,一起跟随丸趣 TV 小编过来看看吧。
一、ARM 体系结构
ARM(Advanced RISC Machines),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。ARM 处理器是一种低功耗高性能的 32 位 RISC 处理器,基于 ARM 的处理器以其高速度、低功耗等诸多优异的性能而得到非常广泛的应用。
ARM 公司在经典处理器 ARM11 以后的产品改用 Cortex 命名,并分成 A、R 和 M 三类,其分别应用于不同的领域。Cortex 系列属于 ARMv7 架构,其中“A”系列面向尖端的基于虚拟内存的操作系统和用户应用;“R”系列针对实时系统;“M”系列对微控制器。在 ARM11 推出前,其处理器比较:
ARM7ARM9ARM10ARM11 流水线 3 级 5 级 6 级 8 级典型频率 MHz80150260335 功耗 mW/MHz0.060.19(+cache)0.5 (+cache)0.4 (+cache)性能 MIPS/MHz0.971.11.31.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 = 0Z 位如果指令的结果为 0,则置 1(通常用来表示比较的结果为“相等”);否则置 0C 位表示运算的进位、借位等 V 位益出标志位 Q 标志位在带 DSP 指令扩展的 ARM v5 及更高版本中,bit[27]被指定用于指示增强的 DAP 指令是否发生了溢出,因此也就被称为 Q 标志位。同样,在 SPSR 中 bit[27]也被称为 Q 标志位,用于在异常中断发生时保存和恢复 CPSR 中的 Q 标志位。在 ARM v5 以前的版本及 ARM v5 的非 E 系列处理器中,Q 标志位没有被定义,属于待扩展的位。I = 1IRQ 被禁止 F = 1FIQ 被禁止 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 的指令系统
在嵌入式开发中,汇编程序常常用于非常关键的地方,比如系统启动时的初始化,进出中断时的环境保存、恢复,对性能要求非常苛刻的函数等。ARM 微处理器的指令集主要有 6 大类:跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载 / 存储指令、协处理器指令、异常产生指令。
2.1 跳转指令
跳转(B)和跳转连接(BL)指令是改变指令执行顺序的标准方式。ARM 一般按照字地址顺序执行指令,需要时使用条件执行跳过某段指令。只要程序必须偏离顺序执行,就要使用控制流指令来修改程序计数器。主要有三条指令:
指令语法格式跳转范围跳转指令 B 及带连接的跳转指令 BLB{L}{cond} target_address PC+-32MBBX 带状态切换的跳转指令 BXBX{cond} Rm 绝对地址 4GBXL 带状态切换的连接跳转指令 BLXBLX 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 指令集中提供了两条产生异常的指令,通过这两条指令可以用软件的方法实现异常。
三、ARM-THUMB 子程序调用规则 ATPCS
为了使 C 语言程序和汇编程序之间能够互相调用,必须为子程序间的调用制定规则,在 ARM 处理器中,这个规则被称为 ATPCS:ARM 程序和 Thumb 程序中子程序调用的规则。基本的 ATPCS 规则包括寄存器使用规则、数据栈使用规则、参数传递规则。
3.1、寄存器使用规则
ARM 处理器中有 r0~r15 共 16 个寄存器,它们的用途有一些约定的习惯,并依具这些用途定义了别名,如下表所示:
寄存器别名使用规则 TextTextTextr15pc 程序计数器 r14lr 连接寄存器 r13sp 数据栈指针 r12ip 子程序内部调用的 scratch 寄存器 r11v8ARM 状态局部变量寄存器 8r10v7、s1ARM 状态局部变量寄存器 7、在支持数据栈检查的 ATPCS 中为数据栈限制指针 r9v6、sbARM 状态局部变量寄存器 6、在支持 RWPI 的 ATPCS 中为静态基址寄存器 r8v5ARM 状态局部变量寄存器 5r7v4、wrARM 状态局部变量寄存器 4、Thumb 状态工作寄存器 r6v3ARM 状态局部变量寄存器 3r5v2ARM 状态局部变量寄存器 2r4v1ARM 状态局部变量寄存器 1r3a4 参数 / 结果 /scratch 寄存器 4r2a3 参数 / 结果 /scratch 寄存器 3r1a2 参数 / 结果 /scratch 寄存器 2r0a1 参数 / 结果 /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 体系结构与常用汇编指令是什么”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!