当前位置:   article > 正文

ARM 体系知识总结_mla r1mla,r3;r0;寻址方式

mla r1mla,r3;r0;寻址方式

参考


  1. 转载;

ARM 处理器简介和RISC特点


ARM 处理器简介

ARM(Advanced RISC Machines)是一个32位RISC(精简指令集)处理器架构,ARM处理器则是ARM架构下的微处理器。ARM处理器广泛的使用在许多嵌入式系统。ARM处理器的特点有指令长度固定,执行效率高,低成本等。


RISC 设计主要特点

  • 指令集——RISC减少了指令集的种类,通常一个周期一条指令,采用固定长度的指令格式,编译器或程序员通过几条指令完成一个复杂的操作。而CISC指令集的指令长度通常不固定;
  • 流水线——RISC采用单周期指令,且指令长度固定,便于流水线操作执行;
  • 寄存器——RISC的处理器拥有更多的通用寄存器,寄存器操作较多。例如ARM处理器具有37个寄存器;
  • Load/Store结构——使用加载/存储指令批量从内存中读写数据,提高数据的传输效率;
  • 寻址方式简化,指令长度固定,指令格式和寻址方式种类减少。

ARM 的基本数据类型


  • 双字节(DoubleWord):64位
  • 字(Word):在ARM体系结构中,字的长度为32位。
  • 半字(Half-Word):在ARM体系结构中,半字的长度为16位。
  • 字节(Byte):在ARM体系结构中,字节的长度为8位。

ARM 处理器存储格式


ARM体系结构将存储器看作是从0地址开始的字节的线性组合。作为32位的微处理器,ARM体系结构所支持的
最大寻址空间为4GB。ARM体系结构可以用两种方法存储字数据,分别为大端模式和小端模式。

  • 大端模式(高地高低):字的高字节存储在低地址字节单元中,字的低字节存储在高地址字节单元中。
  • 小端模式(高高低低):字的高字节存储在高地址字节单元中,字的低字节存储在低地址字节单元中。

内核的工作模式


  • 用户模式(user):正常程序执行模式;
  • 快速中断模式(FIQ):高优先级的中断产生会进入该种模式,用于高速通道传输;
  • 外部中断模式(IRQ):低优先级中断产生会进入该模式,用于普通的中断处理;
  • 特权模式(Supervisor):复位和软中断指令会进入该模式;
  • 数据访问中止模式(Abort):当存储异常时会进入该模式;
  • 未定义指令中止模式(Undefined):执行未定义指令会进入该模式;
  • 系统模式(System):用于运行特权级操作系统任务;
  • 监控模式(Monitor):可以在安全模式和非安全模式之间切换;

ARM9 的 5 级流水线:


流水线的执行顺序:取指令->译码->执行->缓冲/数据->回写

  • 取指令(Fetch):从存储器读取指令;
  • 译码(Decode):译码以鉴别它是属于哪一条指令;
  • 执行(Execute):将操作数进行组合以得到结构或存储器地址;
  • 缓冲/数据(Buffer/data):如果需要,则访问存储器以存储数据;
  • 回写(Write-back):将结果写回寄存器组中;

影响流水线性能的因素:

  • 互锁:不同的指令顺序也会造成时钟周期的不同,比如一条指令的执行需要前一条指令的结果;如果此时前一条指令结果还没有出来,那就需要等待,这就是流水线互锁;
LDR r1, [r2, #4]
ADD r0, r0, r1 // r1 的值要等待 LDR 的结果
  • 1
  • 2
  • 跳转指令:跳转指令会破坏流水线的行为,后续指令的取值步骤受到跳转目标的影响。

寄存器组

  • ARM Cortex-A8 处理器有 40 个 32 位的寄存器;

    • 32个通用寄存器;
    • 7个状态寄存器:1 个 CPSR (当前状态寄存器);6 个 SPSR (备份程序状态寄存器);
    • 1 个 PC 寄存器(程序计数器);
  • 每一种处理器模式有一组与之对应的寄存器组,如下对应方式:
    在这里插入图片描述

  • 通用寄存器 R0 - R7:

    • 未分组寄存器 R0-R7:在所有运行模式下,未分组寄存器都指向同一个物理寄存器,他们未被系统用作特殊的用途。因此在中断或异常处理进行异常模式转换时,由于不同的处理器运行模式均使用相同的物理寄存器,所以可能造成寄存器中数据的破坏。
    • 分组寄存器 R8-R14:
      • 对于分组寄存器,他们每次所访问的物理地址寄存器都与当前的处理器运行模式相关;
      • R13 常用作存放堆栈指针,用户也可以使用其他寄存器存放堆栈指针,称为 SP;
      • R14 称为链接寄存器 (LR),当执行子程序时,R14 可得到 R15(PC)的备份,执行完子程序,又将 R14 的值复制回 PC,即使用 R14 保存返回地址;
    • 程序计数器 PC (R15):寄存器 R15 用作程序计数器(PC),在ARM状态下,位 [1:0] 为 0,位 [31:2] 用于保存 PC;在 Thumb 状态下 位[0] 为 0;位[31:1]用于保存PC。对于ARM指令集而言,PC总是指向当前指令的下两条指令的地址,即 PC 的值为当前指令的;地址值加 8 个字节;
  • 程序状态寄存器 CPSR(Current Program Status Register,当前程序状态寄存器),CPSR 可在任何运行模式下被访问,它包括条件标志位、中断禁止位、当前处理器模式标志位以及其他一些相关的控制和状态位。包含以下内容:

    • ALU 状态标志的备份;
    • 当前的处理模式;
    • 中断使能标志;
    • 设置处理的状态;
      每一种运行模式下都有一个专用的物理状态寄存器,称为SPSR(Saved Program Status Register,备份的程序状态寄存器),当异常发生时,SPSR 用于保存当前 CPSR 的值,从异常退出时则可由 SPSR 来恢复 CPSR。
      由于用户模式和系统模式不属于异常模式,这两种状态下没有 SPSR,因此在这两种状态下访问 SPSR,结果是未知的。
      在这里插入图片描述
      在这里插入图片描述

ARM 指令集


数据操作指令:

  • MOV:将数据从一个寄存器传送到另一个寄存器
MOV AX,2000H;// 将 16 位数据 2000H 传送到 AX 寄存器
MOV AL,20H;// 将 8 位数据 20H 传送到 AL 寄存器
MOV AX,BX;// 将 BX 寄存器的 16 位数据传送到 AX 寄存器
MOV AL,[2000H];// 将 2000H 单元的内容传送到 AL 寄存器
MOVW // 把 16 位立即数放到寄存器的低16位,高16位清0
MOVT  // 把 16 位立即数放到寄存器的高16位,低 16位不影响
movw r8, #19028 ; 0x4a54 // 把 0x4a5a 放到寄存器 r8 的低 16 位,r8 高 16位清零; 
movt r8, #49456 ; 0xc130 // 把 0xc130 放到寄存器 r8 的高 16 位;
r8 = 0xc1304a54
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • AND:逻辑与操作
AND R2,R1,R3 // R2 = R1 & R3
ANDS R0,R0,#0x01 // R0 = R0 & 0x01
  • 1
  • 2
  • SUB:减法操作
SUB R0,R1,R2 // R0 = R1 – R2
SUB R0,R1,#256 // R0 = R1 -256
  • 1
  • 2
  • ADD:加法操作
ADD R0,R1,R2  // R0 = R1 + R2
ADD R0,R1,#256  // R0 = R1 + 256
ADD R0,R2,LSL#1 // R0 = R2 + (R3 << 1)
  • 1
  • 2
  • 3
  • CMP 比较指令;
  • BIC 位清零指令
BIC R0, R0, #0X1011 // 清除位 0/1/3
  • 1

乘法指令

  • MUL MLA
MUL R1,R2,R3 //R1 = R2 * R3
MOV R0,#0x0A
MLA R1,R2,R3,R0 // R1 = R2 * R3 + 10
  • 1
  • 2
  • 3

Load/Store指令

  • LDR 从存储器中将一个 32 位的字数据传送到目的寄存器中。
LDR R1,[R0,#0x12]             // 将 R0 +12 地址处的数据读出,保存到 R1 中;
LDR R1,[R0,R2]                  // 将 R0 + R2 地址的数据读出,保存到 R1 中;
LDR RD,[Rn],#0x04            // Rn 的值用作传输数据的基地址,在数据传送后,将偏移量0x04与Rn相加写回到RD中
LDR R0,[R1,LSL #3]           // 将存储器地址为R1*8的字数据读入寄存器R0。
LDR R0,[R1,R2,LSL #2]   // 将存储器地址为R1+R2*4的字数据读入寄存器R0。
LDR R0,[R1,R2,LSL #2]! // 将存储器地址为R1+R2*4的字数据读入寄存器R0,并将R1+R2*4的值存入R1。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • STR 用于将一个 32bit 的数据写入到指定的内存单元
STR R0,[R1],#8  // 将 R0 中的字数据写入以 R1 为地址的存储器中,并将新地址 R1+8 写入 R1。
STR R0,[R1,#8]  // 将 R0 中的字数据写入以 R1+8 为地址的存储器中
STR R1, [R0]     // 将 R1 寄存器的值,传送到地址值为 R0 的(存储器)内存中
  • 1
  • 2
  • 3

跳转指令

  • B 跳转指令
  • BL 带返回的连接跳转
  • BX 跳转并切换状态
  • BLX 带返回的跳转并切换状态

状态操作指令

ARM 指令提供了两条如下指令,可直接控制程序状态寄存器(只有在特权模式下才能修改状态寄存器):

  • MRS: 把程序状态寄存器的值送到一个通用寄存器中
MRS R1, CPSR      // 将 CPSR 状态寄存器读出,保存到R1中
MRS R2, SPSR
  • 1
  • 2
  • MSR:把寄存器的内容传送到程序状态寄存器
MSR CPSR_c,#0xD3      // CPSR[7:0] = 0xD3切换到管理模式
MSR CPSR_c,R3         // CPSR = R3
  • 1
  • 2

异常产生指令:

  • SWI:软中断指令,产生软中断,处理器进入管理模式;
SWI 0                   // 产生软中断,中断立即数为0
SWI 0x123456     // 产生软中断,中断立即数为0x123456
  • 1
  • 2
  • BKPT:断点中断指令,处理器产生软件中断,产生一个预取异常,用来设置软件断点;

ARM 指令的寻址方式


  • 立即数寻址:
MOV R0,#0                   // 送0到R0中
ADD R3,R3,#1            // R3的值加1
CMP R7,#1000              // R7的值和1000比较
BIC R9,R8,#0xff00      // 将R8中8~15位清0,结果保存在R9中
  • 1
  • 2
  • 3
  • 4
  • 寄存器寻址:寄存器的值可以被直接用于数据操作指令
MOV R2,R0              // R0的值送R2
ADD R4,R3,R2      // R4 = R2 + R3
CMP R7,R8              // 比较R7和R8的值
  • 1
  • 2
  • 3
  • 寄存器移位寻址:预处理和移位发生在同一周期内,有效使用移位寄存器,可以提供代码执行效率;
ADD R2,R0,R1,LSR #5
MOV R1,R0,LSL #2
RSB R9,R5,R5,LSL #1
SUB R1,R2,R0,LSR #4
  • 1
  • 2
  • 3
  • 4
  • 寄存器间接寻址:
LDR R1,[R2]      // 将R2的数值作为地址,取出地址中的数据保存到R1中
STR R1,[R2]      // 将R2数值作为地址,取出R1中的值存入R2所指向的地址
  • 1
  • 2
  • 基址变址寻址:基址变址是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址;基址变址寻址常用于查表、数组操作、访问基址附近的存储单元等。
LDR R1,[ R0,#0xf ]      // 将 R0 的数值加 0x0f 作为地址,取出此地址的数值保存到 R1
STR R1,[R0,#-2]          // 将 R0 的数值减 2 作为地址,将 R1 中的内容保存到此地址中
STR R1,[R0,+R2]         // 将 R0 的值加上 R2 的值作为地址,把 R1 的内容保存到该地址
  • 1
  • 2
  • 3
  • 多寄存器寻址/块拷贝寻址:批量Load、Store指令将一片连续的内存单元数据加载到通用寄存器组中,或将一组通用寄存器的数据存储到内存单元中:
    • IA :后递增方式
    • IB :先递增方式
    • DA:后递减方式
    • DB:先递减方式
    • 块拷贝寻址指令:STMIA、STMIB;
  • 相对寻址:
BL FUN1 //调用到FUN1的子程序
B LOOP //条件跳转到LOOP标号处
STMDA
STMDB
  • 1
  • 2
  • 3
  • 4

异常中断


硬件中断&软件中断:

  • 硬件中断是随机的,不可预测的
  • 软件中断是事先安排的(如workQueue、task)

ARM处理器有七种类型的异常::

  • 复位异常(Reset):处理器在工作时, 突然按下重启键, 就会触发该异常;
  • 数据异常(Data Abort):读取数据失败;
  • 快速中断异常(FIQ):快速中断要比普通中断响应速度要快一些;
  • 外部中断异常(IRQ):普通中断;
  • 预取异常(Prefetch Abort):预取指令失败, ARM 在执行指令的过程中, 要先去预取指令准备执行,如果预取指令失败, 就会产生该异常;
  • 软中断异常(SWI):软件中需要去打断处理器工作, 可以使用软中断来执行 ;
  • 未定义指令异常(Undefined Instruction):处理器无法识别指令的异常, 处理器执行的指令是有规范的,如果尝试执行不符合要求的指令, 就会进入到该异常指令对应的地址中;当异常发生时,分组寄存器R14和SPSR用于保存处理器状态,异常返回时,SPSR内容恢复到SPSR,链接寄存器R14的内容恢复到程序计数器PC。下图中每种异常对应一种内核的工作模式,当然每种异常产生,内核都会进入特定的工作模式;
    在这里插入图片描述
      

异常处理流程:

  • 中断响应所做的工作:
    • 保存短点:保存下一将要执行的指令的地址,也就是把这个地址送入堆栈;
       - 寻找中断入口:根据不同的中断源产生的中断,查找不同的入口地址;
       - 执行中断处理程序;
       - 中断返回:执行完中断指令后,就从中断返回到主程序继续执行;

异常向量表

每一个异常发生时,总是从异常向量表开始跳转,所谓的异常向量表,是指由7个异常向量及其处理函数跳转
关系组成的表:

0x00000000: b reset
0x00000004: ldr pc, _undefined_instruction
0x00000008: ldr pc, _software_interrupt
0x00000008: ldr pc, _software_interrupt
0x0000000c: ldr pc, _prefetch_abort
0x00000010: ldr pc, _data_abort
0x00000014: ldr pc, _not_used //保留
0x00000018: ldr pc, _irq
0x0000001c: ldr pc, _fiq
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

当一个ARM异常返回时,需要完成如下任务:

  • 通用寄存器的恢复;
  • 状态寄存器的恢复;
  • PC指针的恢复;
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/971985
推荐阅读
相关标签
  

闽ICP备14008679号