0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深度剖析ARM内核寄存器及基本汇编语言1

jf_78858299 来源:矜辰所致 作者:矜辰所致 2023-04-24 09:59 次阅读
对于嵌入式开发者来说,了解汇编语言和内核寄存器是对内核深入理解的基础
 ..增加 2.2 汇编伪指令 章节					2021/12/12
 ..完善 2.3 ARM汇编指令集						2021/12/12
 ..增加 3.1 不同编译器的反汇编					2021/12/14 
 ..增加 3.2 C和汇编 比较分析				        2021/12/15 
 从开始写起也没想到内容有这么多,其中有很多干货的东西,希望自己能够说明到了,
 其中有很多推荐的博文和网站,在此要特别感谢韦东山老师的视频,绝对干货满满
  • 一、ARM内核寄存器
    • 1.1 M3/M4内核寄存器
    • 1.2 A7内核寄存器
    • 1.3 ARM中的PC指针的值
  • 二、ARM汇编语言
    • 2.1 ARM汇编基础
    • 2.2 汇编伪指令
    • 2.3 ARM汇编指令集
  • 三、代码反汇编简析
    • 3.1 不同编译器的反汇编
    • 3.2 C 和 汇编 比较分析

开头直接来看几个简单的汇编指令:

MOV R0,R1``MOV PC,R14

上面的指令中使用了汇编 MOV指令,但是其中的 R0,R1,R14,PC分别是什么?哪来的?怎么用?

要讲 ARM 汇编语言,必须得先了解ARM的内核寄存器,内核处理所有的指令计算,都需要用到内核寄存器,所以ARM汇编里面指令大都是基于寄存器的操作。

文章前推荐韦东山老师的单片机核心视频,视频可以在韦东山老师官网里面找到:百问网

ARM版本简单介绍:

内核(架构)版本 处理器版本
ARMv1 ARM1
ARMv2 ARM2、ARM3
ARMv3 ARM6、
ARMv4 ARM7、StrongARM
ARMv5 ARM9、ARM10E
ARMv6 ARM11
ARMv7 ARM Cortex-A、ARM Cortex-M、ARM Cortex-R
ARMv8 ARM Cortex-A30、ARM Cortex-A50、ARM Cortex-A70

一、ARM内核寄存器

内核寄存器与外设寄存器:

内核寄存器与外设寄存器是完全不同的概念。内核寄存器是指 CPU 内部的寄存器,CPU处理所有指令数据需要用到这些寄存器保存处理数据;外设寄存器是指的 串口,SPI,GPIO口这些设备有关的寄存器。

在我的另一篇博文:FreeRTOS记录(三、FreeRTOS任务调度原理解析_Systick、PendSV、SVC)内核中断管理 章节讲到过Cortex-M的寄存器的相关内容,这里我们再简单说明一下:

1.1 M3/M4内核寄存器

对于M3/M4而言:图片R13,栈指针(Stack Pointer)

  • R13寄存器中存放的是栈顶指针,M3/M4 的栈是向下生长的,入栈的时候地址是往下减少的。
  • 裸机程序不会用到PSP,只用到MSP,需要运行RTOS的时候才会用到PSP。
  • 堆栈主要是通过POP,PUSH指令来进行操作。在执行 PUSH 和 POP 操作时, SP 的地址寄存器,会自动调整。

R14 ,连接寄存器(Link Register)

  • LR 用于在调用子程序时存储返回地址。例如,在使用 BL(分支并连接, Branch and Link)指令时,就自动填充 LR 的值(执行函数调用的下一指令),进而在函数退出时,正确返回并执行下一指令。如果函数中又调用了其他函数,那么LR将会被覆盖,所以需要先将LR寄存器入栈。
  • 保存子程序返回地址。使用BL或BLX时,跳转指令自动把返回地址放入r14中;子程序通过把r14复制到PC来实现返回
  • 当异常发生时,异常模式的r14用来保存异常返回地址,将r14如栈可以处理嵌套中断

R15,程序计数器(Program Count)

  • 在Cortex-M3中指令是3级流水线,出于对Thumb代码的兼容的考虑,读取pc时,会返回当前指令地址+4的值。
  • 读 PC 时返回的值是当前指令的地址+4,关于M3、M4 和 A7的 PC值的问题需要单独来解释一下

其中程序状态寄存器 XPSR:图片

程序状态寄存器,该寄存器由三个程序状态寄存器组成 应用PSR(APSR) :包含前一条指令执行后的条件标志,比较结果:大于等于,小于,进位等等; 中断PSR(IPSR ) :包含当前ISR的异常编号 执行PSR(EPSR) :包含Thumb状态位

1.2 A7内核寄存器

对于 A7 而言:图片(上图取自原子教材,此图在官方文档《ARM Cortex-A(armV7)编程手册V4.0》中第3章.ARM Processor Modes and Registers 部分有英文原版,这里用中文版本更容易理解)

A7的 R13、R14、R15 的作用和 M3/4类似。

需要注意的一点就是,对于A7而言 R15,程序计数器(Program Count)

  • 读 PC 时返回的值是当前指令的地址+8, PC 指向当前指令的下两条指令地址。
  • 由于ARM指令总是以字对齐的,故PC寄存器 bit[1:0] 总是00。

A7内核的程序状态寄存器 CPSR:图片

1.3 ARM中的PC指针的值

因为ARM指令采用三级流水线机制,所以PC指针的值并不是当前执行的指令的地址值:

  1. 当前执行地址A的指令,
  2. 同时已经在对下一条指令进行译码,
  3. 同时已经在读取下下一条指令:PC = A +4 (Thumb/Thumb2指令集)、PC = A + 8 (ARM指令集)

在文档《ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition》中对于 PC 的值有明确的说明:图片

M3/M4/M0:

PC的值 = 当前地址 + 4;

下面是一个 STM32F103 反汇编程序,找了一段有[pc,#0]的代码,方便判断:图片

A7:

PC的值 = 当前地址 + 8;

图片

二、ARM汇编语言

ARM芯片属于精简指令集计算机(RISC:Reduced Instruction Set Computing),具体说明在下面这篇博文5.4小结有过说明:

STM32的内存管理相关(内存架构,内存管理,map文件分析)

2.1 ARM汇编基础

2.1.1 ARM指令集说明

最初,ARM公司发布了两类指令集:

  1. ARM指令集,32位的ARM指令,每条指令占据32位,高效,但是太占空间;
  2. Thumb指令集,16位的Thumb指令,每条指令占据16位,节省空间;

比如:MOV R0,R1 这条指令,可能是16位的,也可能是32位的

那么在汇编中是如何在 ARM 指令 和 Thumb 指令之间切换呢:

/*ARM指令 与 Thumb 指令 的切换*/

CODE16  ;(表示下面是 Thumb 指令)
...
...

;(调用下面的B函数)
bx  B_addr;(B的地址B_addr的bit0 = 0,表示跳转过去执行 ARM 指令)
;A 函数
...

CODE32  ;(表示下面是 ARM 指令)
...
...
;B 函数
;(回到上面的A函数)
bx  A_addr + 1 ;(A的地址A_addr的bit0 = 1,表示跳转过去执行 Thumb 指令)
...

/**********************/

对于A7、ARM7、ARM9 内核而言它们支持 16位的Thumb 指令集 和 32位的 ARM 指令集

对于M3、M4 内核而言它们支持的是 Thumb2 指令集,它支持16位、32位指令混合编程

对于内核来说使用的是 ARM指令集 还是 Thumb指令集,就是在 XPSR 和 CPSR

在M3/M4中, XPSR 寄存器的 T(bit24):1表示 Thumb指令集图片根据上面所述,M3是使用的 Thumb2 指令集,所以会有 T 总是 1.

在A7中 CPSR中的:T(bit5) :控制指令执行状态,表明本指令是 ARM 指令还是 Thumb 指令,通常和 J(bit24)一起表明指令类型图片

J(bit24) T(bit5) 指令集
0 0 ARM
0 1 Thumb
1 1 ThumbEE -- 提供从Thumb-2而来的一些扩充性,在所处的运行环境下,使得指令集能特别适用于运行阶段的编码产生(例如实时编译)。Thumb-2EE是专为一些语言如Limbo、JavaC#、Perl和Python,并能让实时编译器能够输出更小的编译码却不会影响到性能。
1 0 Jazelle

回到开始的指令 MOV R0,R1

code 16  ;(表示下面指令是16位的 Thumb 指令)
MOV R0,R1
code 32  ;(表示下面指令是32位的 ARM 指令)
MOV R0,R1
Thumb    ;(编译器会根据指令自动识别是32位还是16位的 Thumb2MOV R0,R1

2.1.2 ARM汇编格式

编码格式:

不同指令集的编码格式(以 LDR 为例),摘自《ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition》:图片以“数据处理”(其他的还有内存访问,分支跳转等)指令为例,UAL汇编格式为:图片Operation

表示各类汇编指令,比如 ADD、MOV;cond表示conditon,即该指令执行的条件,如 EQ,NE 等;S表示该指令执行后,是否会影响CPSR寄存器的值, 是否影响CPSR 寄存器的值,书写时影响CPSR,否则不影响;Rd

为目的寄存器,用来存储运算的结果;Rn 第一个操作数的寄存器Operand2第二个操作数 ,其可以有3种操作源:1-- 立即数 2-- 寄存器 3-- 寄存器移位

其指令编码格式如下(32位):|bit 31-28 |27-25 |24-21 |20 |19-16 | 15-12 |11-0 | |--|--|--|--|--|--|--|--|--| |cond | 001 |Operation |S |Rn |Rd | Operand2 |

举个例子:

...
CMP R0,R2      ;比较R0和R2的值
MOV EQ R0,R1  ;加上EQ,如果上面R0的值和R2的值相等的话,才执行此语句
...

对于“数据处理”处理指令中的Operation ,指令集如下:图片对于其中的条件cond ,如下:图片

2.1.3 立即数

在一条ARM数据处理指令中,除了要包含处理的数据值外,还要标识ARM命令名称,控制位,寄存器等其他信息。这样在一条ARM数据处理指令中,能用于表示要处理的数据值的位数只能小于32位;

在上面的ARM汇编格式中我们介绍过,ARM在指令格式中设定,只能用指令机器码32位中的低12位来表示要操作的常数。图片

那么对于指令MOV R0, #value(把value的值存入R0寄存器)而言,value 的值也不能是任意的值,其值只能是符合某些规定的数,在官方文档中 value 的值需要满足如下条件:图片什么是立即数?

满足上图中条件的数我们称之为 立即数,立即数就是符合一定规矩的数。

立即数表示方式:每个立即数由一个8位的常数循环右移偶数位得到。其中循环右移的位数由一个4位二进制的两倍表示。

立即数 = 一个8位的常数 循环位移 偶数位

一个8bit常数循环右移(Y*2 = {0,2,4,6,8, ...,26, 28, 30})就得到一个立即数了;(为什么是0到30的偶数下面解释)

如果需要深入理解立即数,推荐一篇博文:深刻认识 -->> 立即数

ARM处理器是按32位来处理数据的,ARM处理器处理的数据是32位,为了扩展到32位,因此使用了构造的方法,在12位中用8位表示基本数据值,用4位表示位移值,通过用8位基本数据值往右循环移动4位位移值*2次,来表示要操作的常数。

这里要强调最终的循环次数是4位位移值乘以2得到的,所以得到的最终循环次数肯定是一个偶数,为什么要乘以2呢,实质还是因为范围不够,4位表示位移次数,最大才15次(移位0,等于没有循环),加上8位数据还是不够32位,这样只能通过ALU的内部结构设计将4位位移次数乘以2,这样就能用12位表示32位常数了。

所以 12bit 数据存放格式如下:|bit 11-8 |7-0 | |--|--|--|--|--|--|--|--|--| |移位 1111b (0~15) | 8bit常数 |

但是我们去判断一个数是否立即数,实在是太麻烦了,但是我们想把任意数值赋给 R0 寄存器,怎么办? 这就需要用到伪指令了,下面说一说什么是伪指令。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    9040

    浏览量

    366726
  • 寄存器
    +关注

    关注

    31

    文章

    5308

    浏览量

    119978
  • PC
    PC
    +关注

    关注

    9

    文章

    2065

    浏览量

    153998
  • 汇编语言
    +关注

    关注

    14

    文章

    409

    浏览量

    35730
收藏 人收藏

    评论

    相关推荐

    汇编语言长什么样子的呢

    文章目录汇编语言长什么的样子呢?ARM汇编指令条件和状态Status码ARM汇编寻址方式数据操作(ALU操作)逻辑操作(与,或,非,异或)比
    发表于 12-14 07:28

    如何用C语言寄存器汇编语言去实现流水灯

    目录一、初始化1、地址映射和寄存器映射2、接线3、程序下载二、用C语言寄存器实现流水灯三、汇编语言实现流水灯四、心得一、初始化
    发表于 02-10 07:55

    ARM汇编语言与指令格式资料分享

    1ARM汇编语言与指令格式介绍汇编语言介绍概念指的是用助记符代替操作码,用地址符号或标签(:#&)代替地址码的编程语言。优缺点优点
    发表于 04-22 16:10

    汇编语言教程-段寄存器的说明语句

    汇编语言教程-段寄存器的说明语句   在汇编语言源程序中可以定义多个段,每个段都要与一个段寄存器建立一种对应关系。建立这
    发表于 03-27 17:17 1389次阅读

    ARM汇编语言官方手册(中文)

    ARM汇编语言官方手册(中文)汇编语言ARM汇编语言官方手册(中文)
    发表于 12-28 15:02 212次下载

    汇编语言

    汇编语言举例,比如读寄存器内容的源代码、汇编语言制作的光带菜单及源程序、获得操作系统版本的汇编源代码等
    发表于 12-31 10:40 33次下载

    51单片机汇编语言教程_单片机的特殊功能寄存器

    51单片机汇编语言教程:7课单片机的特殊功能寄存器
    发表于 01-19 15:26 0次下载

    汇编语言学习

    寄存器 一个cpu有多个寄存器 就是cpu中可以存储数据的器件,一个cpu中有多个寄存器汇编语言由一下3类组成 1
    发表于 11-23 18:06 14次下载
    <b class='flag-5'>汇编语言</b>学习

    [从零学习汇编语言] -寄存器详解

    文章目录前言一、 存储与通用寄存器1. 存储2. 通用寄存器前言上一章我们曾简单的介绍过计算机中的一些硬件和软件的相关概念,还不熟悉的小
    发表于 11-26 20:51 8次下载
    [从零学习<b class='flag-5'>汇编语言</b>] -<b class='flag-5'>寄存器</b>详解

    [从零学习汇编语言] - 寄存器与内存访问

    [从零学习汇编语言] - 寄存器与内存访问
    发表于 11-26 20:51 13次下载
    [从零学习<b class='flag-5'>汇编语言</b>] - <b class='flag-5'>寄存器</b>与内存访问

    ARM汇编语言官方手册

    ARM汇编语言官方手册
    发表于 10-10 10:44 29次下载

    深度剖析ARM内核寄存器及基本汇编语言2

    M3/M4内核寄存器 * 1.2 A7内核寄存器 * 1.3 ARM中的PC指针的值 * 二、
    的头像 发表于 04-24 10:00 1048次阅读
    <b class='flag-5'>深度</b><b class='flag-5'>剖析</b><b class='flag-5'>ARM</b><b class='flag-5'>内核</b><b class='flag-5'>寄存器</b>及基本<b class='flag-5'>汇编语言</b>2

    深度剖析ARM内核寄存器及基本汇编语言3

    M3/M4内核寄存器 * 1.2 A7内核寄存器 * 1.3 ARM中的PC指针的值 * 二、
    的头像 发表于 04-24 10:01 1181次阅读
    <b class='flag-5'>深度</b><b class='flag-5'>剖析</b><b class='flag-5'>ARM</b><b class='flag-5'>内核</b><b class='flag-5'>寄存器</b>及基本<b class='flag-5'>汇编语言</b>3

    单片机汇编语言的结构/数据类型/汇编指令

    开发汇编语言是为了为机器级代码指令提供助记符或符号,汇编语言程序由助记符组成,因此应将它们翻译成机器代码。负责这种转换的程序称为汇编程序。汇编语言通常被称为低级
    的头像 发表于 07-07 12:28 2892次阅读

    ARM汇编语言工具

    电子发烧友网站提供《ARM汇编语言工具.pdf》资料免费下载
    发表于 11-06 09:12 0次下载
    <b class='flag-5'>ARM</b><b class='flag-5'>汇编语言</b>工具