ARM编程——ARM架构及汇编

简介: ARM编程——ARM架构及汇编

文章目录

ARM体系结构与编程

ARM7(ARMV4)和ARM9之后的指令操作流程

ARM7(ARMV4)三级指令流水线

三级流水线

**PC**

ARM7三级流水线特例——ldr指令

ARM7三级流水线特例——bl指令

ARM7三级流水线特例——中断

ARM9(ARMV4)以后的ARM核的五级指令流水线

ARM编程模型

ARM核的七种工作模式

ARM核的两种工作状态

ARM核的37个寄存器

ARM支持的数据类型

ARM支持大端和小端模式,默认小端模式

ARM汇编语法格式:

ARM异常

ARM一旦触发异常会如何处理

ARM核跳转的方式

ARM指令——分支跳转指令


ARM体系结构与编程

当前ARM核的版本划分,


  • ARMV4:这其中包含的小版本有:
  • ARM720T
  • ARM920T
  • ARMV5:
  • Xscale
  • ARM10
  • ARMV6:
  • ARM11
  • ARMV7:
  • ARM-CORTEX-A8
  • ARM-CORTEX-A9
  • ARM-CORTEX-A15
  • ARM-CORTEX-M3/M0 STM32(M3)主打控制处理
  • ARMV8:(正式支持64位)
  • ARM-CORTEX-A53
  • ARM-CORTEX-A57

ARM7(ARMV4)和ARM9之后的指令操作流程

ARM7使用的是三级指令流水线,但是ARM9和ARM9之后的版本都使用五级指令流水线。其中需要说明:


  • 指令:给CPU核下发的命令,CPU核根据命令完成一个功能。(例如:给CPU核发一个add指令,就是告诉CPU核做数据的加法运算)
  • 指令在哪里呢:指令就是存在于二进制可执行文件中,CPU核要想执行指令,首先将指令对应的二进制文件加载到内存中,指令最终存在于内存中,内存的访问以地址的执行访问,所以每一条指令也有对应的内存存储地址,当CPU要想运行一条指令,首先从内存中获取到指令。
  • 注意: CPU核工作在ARM状态下:一条指令的宽度为32位(4字节);CPU核工作在THUMB状态下:一条指令的宽度为16位(2字节)。

ARM7(ARMV4)三级指令流水线

三级流水线

  • 取指:CPU核中的取指器(硬件)从内存中读取要运行的指令。
  • 解码:CPU核取完指令后,该指令还不能直接运行(CPU核不识别),需要使用解码器进行解码成机器码。
  • 执行:解码完成后,CPU核最终执行指令。
  • 总结: 取指(F)->解码(D)->执行(E)


网络异常,图片无法展示
|

网络异常,图片无法展示
|

PC

  • PC是个寄存器,位宽为32位。它是ARM核(CPU核)中的寄存器,用来保存取指器要取的那条指令对应的内存存储地址。

例如:

#内存存储地址  指令
0x48000000  add
0x48000004  sub
0x48000008  and
....


当上述add指令呗执行的时候,取指器取得and指令,所以此时PC=0x48000008。


ARM7三级流水线特例——ldr指令

ldr指令功能:CPU核利用此指令能够从外设中加载数据到CPU核中。

ldr指令流水线分为五级:

取指(F)->解码(D)->执行(E)->访存(M)->写回(W)


说明:


  • 访存:CPU核寻找外设地址。
  • 写回:CPU核一旦找到了外设地址,将外设的数据加载到CPU核中。
  • 注意:ARM7的ldr指令在M和W的时候,跟在其后的两条指令的处理需要延后两个指令周期。

ARM7三级流水线特例——bl指令

bl指令的功能:CPU核执行bl指令,能够跳转到bl指令指定的内存位置去运行(取指->解码->执行)。

bl指令处理流水线需要五级:

取指(F)->解码(D)->执行(E)->保存返回地址(L)->正式跳转(A)


说明:


  • 保存返回地址(L):CPU核跳转到bl指令指定的地址运行之前先把返回地址(bl治疗的下一条指令)进行保存处理。
  • 正式跳转(A):CPU核跑到bl执行指定的地址去运行。

ARM7三级流水线特例——中断

中断定义:中断是计算机非常重要的机制

问:计算机中为什么有中断呢?


  • 中断产生的根本原因就是CPU的数据除了速度远远快于外设的数据处理速度。举个例子:以CPU核读取UART接收缓冲区的数据为例,当CPU核发现UART接收缓冲区没有数据,通常的操作都是轮询方式(死等),判断接收缓冲区有没有数据到来,但是这种放松会大大消耗CPU的利用率,此时此刻就需要用到中断方式操作UART接收缓冲区。当接收缓冲区有数据,UART控制器会给CPU发送一个中断信号告诉CPU有数据到来,CPU就会停止手上的工作转而去处理UART接收数据,之后在回到之前的流程中继续处理刚刚的事情。这样大大提高了CPU的利用率。

CPU核接收到中断信号后,开始处理中断,中断处理流水线需要四级:

切记: 当CPU核正在执行某个处理时,CPU核受到中断信号,CPU核处理中断一定是在当前处理执行完之后再去处理。

解码中断(DI)->执行中断(EI)->保存返回地址(L)->正式跳转(A)


说明:


  • 保存返回地址:中断产生之前,CPU在执行别的指令,当中断到来,CPU核转而执行中断处理函数,处理完还需要再回来继续处理之前的指令,所以需要保存返回地址。

ARM9(ARMV4)以后的ARM核的五级指令流水线

ARM9以后的所有ARM核指令流水线一律采用五级流水线,也就是将访存(M)和写回(W)给每一条指令都添加上。


  • F->D->E->M->W

ARM编程模型

ARM核的七种工作模式

  • SVC管理模式: 当系统复位或者软件执行swi指令,CPU核切换到此模式下。
  • FIQ快速中断模式: 外设给CPU核发送一个FIQ快速中断信号,CPU核会切换到此模式下。
  • IRQ中断模式: 外设给CPU核发送一个IRQ普通中断信号,CPU核切换到此模式。
  • Abort中止模式: 当CPU核取指失败或者访存失败,CPU核进入此模式。
  • undef未定义指令模式: 当CPU核执行一个不认识的指令(lisi),CPU核进入此模式。
  • system系统模式:
  • user用户模式: system和user一样,CPU核正常运行情况下,CPU就会处于这两个模式其中之一。Linux系统下,当CPU处理一个进程时就工作在user模式下。

ARM核的两种工作状态

ARM状态:


  • ARM指令:位宽 32 位。
  • Thumb状态:
  • thumb指令:位宽 16 位。

ARM核的37个寄存器

  • 寄存器:暂存数据的硬件,类似内存
  • 寄存器分类:特殊功能寄存器和ARM寄存器。
  • 特殊功能寄存器:各种硬件控制器内核的寄存器,也就是之前说的CPU通过访问这样一类寄存器都是通过地址指针形式访问。
  • ARM寄存器:仅仅存在于ARM核内部,CPU核访问内部的ARM寄存器通过名字(不论大小写),总共37个ARM寄存器。

ARM核37个寄存器:


  • 31个通用寄存器:r0, r1, r2, … … r15,每一种工作模式下又有自己独立的寄存器。
  • r15又称gc:永远只保存取指器要取的那条指令的内存存储地址。
  • r14又称lr:永远只保存返回地址。
  • r13又称sp:永远只保存栈指针。

6个状态寄存器:


  • 1个cpsr和5个spsr
  • cpsr:又称当前程序状态寄存器,也就是保存当前程序运行状态。
  • spsr:又称备份程序状态寄存器,本质目的就是为了保存cpsr的值。

详解CPSR程序状态寄存器:


  • BIT[4:0]:模式位mode
  • 10000 ,表示当前CPU核处于用户模式。
  • 10011 ,表示当前CPU核处于SVC管理模式。
  • BIT[5]:状态位T
  • 0 - ARM核处于ARM状态
  • 1 - ARM核处于thumb状态
  • BIT[6]:FIQ配置位F
  • 0 - 使能FIQ中断功能
  • 1 - 禁止FIQ中断功能
  • BIT[7]:IRQ配置位T
  • 0 - 使能IRQ中断功能
  • 1 - 禁止IRQ中断功能
  • BIT[28]:溢出标志位V
  • 0 - 表示程序运行结果没有发送溢出。
  • 1 - 表示程序运算结果发送溢出
  • BIT[29]:进位或者借位表示C
  • 0 - 表示程序运算没有发送进位或者借位。
  • 1 - 表示程序运算时发送了进位或者借位。
  • BIT[30]:零位Z
  • 0 - 表示程序运算结果为非0
  • 1 - 表示程序运算结果为0
  • BIT[31]:负或者小于位N
  • 0 - 表示程序运算结果不为负数或者不小于
  • 1 - 表示程序运算结果为负数或者小于
  • BIT[31:28]简称NZCV,只要程序运行,CPSR的值会随时随刻发生改变。

注意:


  • 现在有一个进程获取到CPU资源,此进程就可以投入运行,此时对应的CPU核的工作模式为User用户模式,此时由于CPU核执行进程对应的代码cpsr时刻进行改变,突然UART控制器给CPU核发送一个IRQ中断电信号,此时CPU核就会由 User用户模式切换到IRQ普通中断模式,紧接着CPU核开始去处理IRQ中断,本质就是CPU核去执行这个IRQ中断对应的一个函数而已,此函数也是一个程序,如果此程序运行,将来势必也会影响cpsr,但是将来中断处理完毕CPU核还要返回到原先被打断的进程继续运行,为了让原先的进程能够继续正确运行,所以CPU核在处理中断之前,先把当前进程的cpsr的值备份到IRQ模式下的spsr,将来中断返回 只需从IRQ模式下的spsr恢复原先进程的cpsr。

ARM支持的数据类型

Byte:1字节

HalfWord:2字节

Word:4字节

DoubleWord:8字节


ARM支持大端和小端模式,默认小端模式

X86是小端,PowerPC是大端。


ARM汇编语法格式:

参考代码:


.text @代码段的起始
.code 32 @使用ARM指令
.global start @声明一个全局标签start
start: @全局标签的内容如下
  mov r0, #10 @r0=10
  ldr r1, =3  @r1=3
  add r0, r0, r1@r0=r0+r1
  b .  @while(1);
.end @代码段的结束


切记:影响CPSR的NZCV位的两种情形:


  • 1.指令后面加s,运算结果影响CPSR的NZCV

add r0, r0, r1 #@r0=1,r1=-1
  #@r0保存运算结果,不影响CPSR的NZCV
   adds r0, r0, r1 #@r0=1,r1=-1 @CPSR的Z=1


  • 2.cmp比较指令后面不加s,运算结果同样影响cpsr

cmp比较指令本质做减法运算

cmp r0, r1 #@本质:运算结果=r0-r1


ARM异常

ARM核有7种异常:


异常 工作模式 CPU核运行地址 场景

复位异常 SVC管理模式 0x00 系统复位

undef未定义指令异常 undef未定义指令模式 0x04 CPU核执行一个不认识的指令

软中断异常 SVC管理模式 0x08 CPU核执行swi指令

预取指令异常 abort中止模式 0x0C CPU核取指失败

数据处理异常 abort中止模式 0x10 CPU核访存失败

IRQ中断异常 IRQ中断模式 0x18 外设给CPU发送IRQ中断电信号

FIQ中断异常 FIQ快速中断模式 0x1C 外设给CPU核发送FIQ快速中断电信号异常

  • 注意:一旦异常发生,CPU核会毫无条件的必须强制跑到对应的入口地址去执行。

ARM一旦触发异常会如何处理

以UART控制器给CPU核发送IRQ中断电信号为例,

理清IRQ异常的处理流程:


  • 1.当UART控制器准备好数据以后,首先会给中断控制器发送一个中断电信号。
  • 2.中断控制器接收到这个中断电信号以后经过一番的判断之后,中断控制器最终以IRQ的形式给CPU核发送一个IRQ中断电信号。
  • 3.CPU核一旦接收到IRQ中断电信号,就会触发一个IRQ异常,CPU核立马要处理这个IRQ异常。

CPU核硬件上自动完成以下工作:


  • 1.把当前程序对应的cpsr的值保存到IRQ中断模式下的spsr_irq

  • 2.设置cpsr,将cpsr的:
  • bit[4:0]=IRQ工作模式对应的值,让CPU核
  • 切换到IRQ中断模式
  • bit[5]=0,让ARM核切换到ARM状态下
  • bit[7:6]=11,禁止ARM核响应IRQ和FIQ中断

  • 3.保存返回地址:lr=pc-4


  • 问:为什么是lr=pc-4呢?
  • 答:例如:
  • 内存地址 指令
  • 0x8000 add
  • 0x8004 sub
  • 0x8008 orr
  • 当add指令执行的时候:pc=0x8008
  • 当add指令执行的时候,触发IRQ异常
  • 将来IRQ异常处理完毕,CPU核返回到0x8004
  • 去运行,所以lr=pc-4=0x8008-4=0x8004
  • 4.设置pc=0x18

  • 问:为什么0x18呢?
  • 答:因为IRQ异常处理的入口地址为0x18
  • 问:pc=0x18代表什么含义呢?
  • 答:本质就是让CPU核跑到0x18地址去运行(F->D->E->M->W)。
  • 问:0x18地址放什么东西?
  • 答:0x18势必放自己编写的软件代码

切记:只要给pc赋值(地址),那么CPU核就会跑到对应的地址去运行。


  • 结论:一旦ARM核做pc=0x18,让CPU核跑到0x18地址去运行,至此正式开启了软件进一步处理IRQ异常的流程。

软件处理IRQ异常的流程:


  • 软件如何处理IRQ异常完全有程序员自行决定,软件处理IRQ异常结束以后,最后让CPU核返回到原先被打断的地方(某个程序)继续执行,软件只需完成以下两个动作即可
  • 实现返回:
  • cpsr=spsr_irq:将IRQ模式下的spsr的值归还给cpsr,spsr_irq保存原先被打断的程序运行的状态。
  • pc=lr:lr保存的返回地址,让CPU核跑到原先被打断的地方继续执行
  • 至此:IRQ异常处理完毕!

ARM核跳转的方式

ARM核跳转的方式有三种:


  • ARM核发生异常,一旦发生异常,ARM核跑到对应的异常入口地址去。
  • ARM核执行b或者bl跳转指令。
  • 直接向pc赋值(此方法最直接)

ARM指令——分支跳转指令

ARM指令集之分支跳转指令:b/bl/bx


b为不带返回的跳转指令


  • 跳转范围相对PC,±32MB

b loop 无条件跳转

beq loop 有条件跳转

bl为待返回的跳转指令


  • 跳转范围相对PC,±32MB

切记:当CPU核执行bl指令时,CPU核硬件上自动将

下一条指令的地址保存在lr中

所以将来软件返回的指令为:mov pc, lr

例如:

内存地址 指令

0x8000 bl strcmp @当bl执行时,pc=0x8008,lr=0x8004

0x8004 add r0, r0, r1

0x8008 sub r0, r0, r1

strcmp:

一大堆指令

mov pc, lr @pc=lr=0x8004,让CPU核跑到0x8004去运行

bx带状态切换的指令(了解)


  • bx跳转的地址的bit[0]=0:切换到ARM状态

bx跳转的地址的bit[0]=1:切换到Thumb状态

例如:

ldr r0, =0x48000000

bx r0 @让CPU核切换到ARM状态并且跳转到0x48000000去运行

ldr r0, =0x48000001

bx r0 @让CPU核切换到Thumb状态并且跳转到0x48000001去运行


相关文章
|
2月前
|
编译器
【ARM汇编速成】零基础入门汇编语言之基本认识(一)
【ARM汇编速成】零基础入门汇编语言之基本认识(一)
|
24天前
|
机器学习/深度学习 弹性计算 人工智能
阿里云服务器架构有啥区别?X86计算、Arm、GPU异构、裸金属和高性能计算对比
阿里云ECS涵盖x86、ARM、GPU/FPGA/ASIC、弹性裸金属及高性能计算等多种架构。x86架构采用Intel/AMD处理器,适用于广泛企业级应用;ARM架构低功耗,适合容器与微服务;GPU/FPGA/ASIC专为AI、图形处理设计;弹性裸金属提供物理机性能;高性能计算则针对大规模并行计算优化。
|
2月前
|
Docker 容器
docker:记录如何在x86架构上构造和使用arm架构的镜像
为了实现国产化适配,需将原x86平台上的Docker镜像转换为适用于ARM平台的镜像。本文介绍了如何配置Docker buildx环境,包括检查Docker版本、安装buildx插件、启用实验性功能及构建多平台镜像的具体步骤。通过这些操作,可以在x86平台上成功构建并运行ARM64镜像,实现跨平台的应用部署。
1572 2
|
2月前
|
编解码 弹性计算 应用服务中间件
阿里云服务器Arm计算架构解析:Arm计算架构云服务器租用收费标准价格参考
阿里云服务器架构分为X86计算、Arm计算、高性能计算等多种架构,其中Arm计算架构以其低功耗、高效率的特点受到广泛关注。本文将深入解析阿里云Arm计算架构云服务器的技术特点、适用场景以及包年包月与按量付费的收费标准与最新活动价格情况,以供选择参考。
|
2月前
|
存储 编译器 C语言
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
|
2月前
|
机器学习/深度学习 弹性计算 编解码
阿里云服务器计算架构X86/ARM/GPU/FPGA/ASIC/裸金属/超级计算集群有啥区别?
阿里云服务器ECS提供了多种计算架构,包括X86、ARM、GPU/FPGA/ASIC、弹性裸金属服务器及超级计算集群。X86架构常见且通用,适合大多数应用场景;ARM架构具备低功耗优势,适用于长期运行环境;GPU/FPGA/ASIC则针对深度学习、科学计算、视频处理等高性能需求;弹性裸金属服务器与超级计算集群则分别提供物理机级别的性能和高速RDMA互联,满足高性能计算和大规模训练需求。
|
2月前
|
设计模式 人工智能 算法
编程之旅:从代码到架构的感悟
【9月更文挑战第33天】在编程的世界里,代码不仅是实现功能的工具,更是连接思想与现实的桥梁。本文将通过个人的编程经历,分享从编写第一行代码到设计系统架构的旅程,探索编程背后的哲学和技术演变。我们将一起思考,如何在代码的海洋中找到自己的航向,以及在这个过程中如何不断成长和适应变化。
|
2月前
|
存储 移动开发 C语言
【ARM汇编速成】零基础入门汇编语言之指令集(三)
【ARM汇编速成】零基础入门汇编语言之指令集(三)
|
2月前
|
编译器 C语言 计算机视觉
【ARM汇编速成】零基础入门汇编语言之指令集(二)
【ARM汇编速成】零基础入门汇编语言之指令集(二)
225 0
|
2月前
|
存储 Docker 容器
ARM架构鲲鹏主机BClinux离线安装docker步骤
下载并安装适用于ARM架构的Docker CE二进制文件,解压后移动至/usr/bin目录。创建docker组,配置systemd服务脚本(docker.service、docker.socket、containerd.service),重载systemd配置,启动并启用docker服务。编辑daemon.json配置存储驱动、镜像加速地址等,最后拉取所需镜像。
67 0
下一篇
DataWorks