day08 ARM体系结构与编程、流水线
来源:互联网 发布:交易宝行情软件 编辑:程序博客网 时间:2024/05/16 01:30
回顾:
1.I2C总线
面试题:谈谈对I2C总线的理解
面试题:谈谈对ARM裸板编程的理解
1.1.常见的几种硬件通信方式
1.2.I2C总线定义
画图
1.3.看图提三个问题
协议
1.4.I2C总线协议概念
1.5.举例子画图说明访问的过程
1.6.举例子画图说明配合
1.7.谈谈调试心得
1.8.以MMA8653三轴加速度传感器的访问为例
谈谈裸板编程的思路
1.用户需求分析
2.掌控硬件信息
粗看
位置
细看
原理图
画图
结论
处理器的手册
I2C控制器以及内部寄存器以指针的形式访问地址
BIT位含义
MMA8653的手册
片内寄存器不能以指针的形式访问,必须严格按照时序图访问
BIT位含义
3.按照裸板编程框架实现代码
谈谈裸板编程框架
顺便谈谈裸板程序的阅读
挑衅:"只要给我一套裸板程序,我就能够理顺程序的执行流程"
1.首先找链接脚本,确定
第一个运行的文件
运行的入口函数
运行的起始地址
2.如果没有链接脚本,看Makeifle
确定运行的第一个文件
第一个文件里指定入口函数
确定运行的起始地址
3.找到了入口函数,利用著名的源码阅读工具sourceinsight和ctags顺藤摸瓜,理顺代码的执行流程,
在阅读时,要将源码和原理图和芯片手册结合起来
4.下位机测试
*************************************************
*************************************************
*************************************************
*************************************************
*************************************************
2.ARM体系结构与编程
面试题:谈谈对ARM处理器的理解
2.1.首先交代常见的几种处理器架构
X86架构:
intel
amd
Powerpc架构:
飞思卡尔
DSP架构:
TI(达芬奇系列:处理器包含DSP核和ARM核)
FPGA架构:
xilinx(ZYNQ系列:处理器包含FPGA核和ARM核)
ARM架构:
华为(海思系列),小米(澎湃),全志(A系列)
MTK,英伟达
高通,TI,Atmel,博通,三星,飞思卡尔等
单片机系列:
51单片机,MSP430,STM32(低端ARM处理器)
"嵌入式处理器":把X86去掉,剩余的都是嵌入式处理器
2.2.何为"ARM",谈谈ARM的定义
ARM既可以认为是一款处理器架构,又可以认为是一家公司(ARM公司)。
ARM公司不生产具体的处理器,而是涉及ARM
做IP授权给各个生产处理器的厂家
例如:S5P6818处理器的CPU核就是ARM公司设计
而其他控制器由三星公司添加
CPU核又称ARM核!
2.3.谈谈ARM的版本划分
明确:ARM的版本仅仅指ARM核的版本(ARM公司定义)
ARM核大版本为:ARMV4/ARMV5/ARMV6/ARMV7/ARMV8
每一个大版本下又分若干个小版本(ARM核)
ARMV4:
小版本 具体的处理器
ARM720T S3C4510(三星)
ARM920T S3C2410(三星)
ARMV5:
Xscale PXA270(intel)
ARM10 S3C6410(三星)
ARMV6:
ARM11 S3C6440(三星)
ARMV7:
ARM-CORTEX-A8 S5PV210(三星)
ARM-CORTEX-A9
ARM-CORTEX-A15
ARM-CORTEX-M3/M0/M3 STM32(M3)主打低端
ARMV8:正式支持64位
ARM-CORTEX-A53 S5P6818(三星)
ARM-CORTEX-A57
2.4.谈谈ARM7(ARMV4)三级指令流水线
1.明确相关概念
"指令":给CPU核下发的命令,CPU核根据命令完成一个功能
例如:给CPU核发一个add指令,就是告诉CPU核做
数据的加法运算
"指令在哪里":指令就是存在于二进制文件中(shell.bin)
CPU核要想执行指令,首先将指令对应的
二进制文件加载到内存中,指令最终
存在于内存中,内存的访问以地址的执行访问
所以每一条指令也有对应的内存存储地址
所以CPU要想运行一条指令,首先从内存中
获取到指令
注意:32位系统:
CPU核工作在ARM状态下:一条指令的宽度为32位(4字节)
CPU核工作在THUMB状态:一条指令的宽度为16位(2字节)
2.CPU核运行一条指令的三级流水线为(仅做了解):
取指:CPU核中的取指器(硬件)从内存中读取
要运行的指令
解码:CPU核取完指令以后,这时候执行还不能
直接去运行(CPU核还不能识别),需要
解码器进行解码翻译
执行: 翻译完成,CPU核最终执行指令
总结:
一条指令CPU核最终运行需要三步:
取指F->解码D->执行E
画出一个三级流水线的操作示意图!
3.PC
PC是个寄存器,位宽为32位,类似监工
它是ARM核(CPU核)中的寄存器
它永远只保存取指器要取的那条指令对应的内存存储地址
例如:
内存存储地址 指令
0x48000000 add
0x48000004 sub
0x48000008 and
... ...
请问:当add指令被执行的时候,PC=?
答:当add执行的时候,取指器取and指令,那么PC=0x480000008
4.ARM7三级流水线特例之ldr指令
ldr指令功能:CPU核利用此指令能够从外设中加载数据到CPU核中
ldr指令流水线为五级:
取指F->解码D->执行E->访存M->写回W
说明:
访存:CPU核找外设地址
写回:CPU核一旦找到了外设地址,将外设的数据
加载到CPU核中
注意:ARM7的ldr指令在M和W的时候,后面的两条指令
的处理要延后两个周期
5.ARM7三级流水线特例之bl指令
bl指令的功能:CPU核执行bl指令,能够跳转到bl指令指定的一个
内存地址去运行(取指->解码->执行)
bl指令处理流水线需五级:
取指F->解码D->执行E->保存返回地址L->正式跳转A
说明:
保存返回地址L:CPU核跳转到bl指令指定的地址运行之前
先把返回地址(bl指令的下一条指令)进行
保存处理
正式跳转A:CPU核跑到bl执行指定的地址去运行
6.ARM7三级流水线特例之中断
中断定义:中断是计算机非常重要的一个机制
问:计算机中为什么有中断呢?
答:中断产生的根本原因就是CPU的数据处理
速度远远快于外设的数据处理速度
举例子说明中断:以CPU核读取UART接收缓冲区的数据为例
当CPU核读取UART接收缓冲区数据时,当CPU核发现接收
缓冲区没有数据,首先会考虑到采用轮训方式(死等)
判断接收缓冲区有没有数据到来,但这种操作方式
会让CPU核不能干其他事情,大大降低了CPU的利用率
此时此刻,一定要想到轮训的死对头中断方式操作UART
接收缓冲区:
当CPU核读取UART接收缓冲区数据时,当CPU核发现接收
缓冲区没有数据,CPU核此时去干别的事情(处理一个算法任务)
一旦将来接收缓冲区有数据到来,UART控制器会给
CPU发送一个中断电信号(嗨,数据到来了)
CPU一旦接收到了UART控制器发送的中断电信号
以后,CPU停止手头正在处理的事情(算法任务)
转去读取UART接收缓冲区的数据,读完以后,CPU
核继续去处理之前被打断的事情(算法任务)
这种CPU至少干两件事,大大提高了CPU的利用率
问:中断电信号的硬件处理是什么样呢?
答:以BT通过UART给CPU核发送数据'A'为例
1.当BT没有或者正在给CPU发送数据'A'时,
此时CPU核去读取数据,此时数据没有准备就绪
CPU核干其他的事情
2.一旦UART控制器将数据接收完毕,UART控制器
首先给中断控制器发送一个中断电信号
3.中断控制器接收到这个中断电信号以后
中断控制器硬件上做一番的判断
4.经过一番判断,中断控制器最终给CPU核发送
一个中断电信号,此中断电信号可以走FIQ
信号线也可以走IRQ信号线
如果是FIQ,此中断信号又称快速中断
如果是IRQ,此中断信号又称普通中断
5.CPU核一旦接收到FIQ或者IRQ中断信号
CPU核停止手头的工作转去处理接收到的
数据'A',处理完毕,CPU核继续处理原先被
打断的事情
CPU核接收到中断信号以后,开始处理中断,
那么中断处理流水线需四级:
切记:当CPU核正在执行某个执行时,如果CPU核
接收到中断信号,CPU核处理中断一定是
在当前执行执行完以后再去处理中断
解码中断DI->执行中断EI->保存返回地址L->正式跳转A
说明:
保存返回地址L:中断产生之前,CPU在别的函数中做事
中断到来,CPU核要跑另一个函数中执行
将来执行完毕,还要返回到原先被打断的
函数中继续执行,所以要想返回先
保存返回地址
2.5.ARM9(ARMV4)以后ARM核的五级流水线
1.ARM9以后的所有ARM核指令流水线一律采用五级
也就是将访存M和写回W给每一条指令都添加上
例如:
三级流水线:add:F->D->E
ldr:F->D->E->M->W
五级流水线:add:F->D->E->(M)->W
ldr:F->D->E->M->W
注意:add/sub/orr/eor/and等指令仅仅是在CPU核内部玩,
无需访问外设,所以无需访存M
但是访问M这个时间(位置)需要保留
画出一个五级流水线的处理示意图!
2.6.ARM编程模型(必考)
1.ARM核的7种工作模式
SVC管理模式
当系统复位或者软件执行swi指令,CPU核切换到此模式下
FIQ快速中断模式
外设给CPU核发送一个FIQ快速中断信号,CPU核切换到此模式下
IRQ中断模式
外设给CPU核发送一个IRQ普通中断信号,CPU核切换到此模式
Abort中止模式
当CPU核取指失败或者访存失败,CPU核进入此模式
Undef未定义指令模式
当CPU核执行一个不认识的指令(lisi),CPU核进入此模式
System系统模式
User用户模式
System和User一样,CPU核正常运行的情况下,CPU核
要不在System模式要不在User模式,linux系统
下,当CPU核处理一个进程时,对应的CPU核为User模式
2.ARM核的两种工作状态
ARM状态
ARM指令
位宽为32位
Thumb状态
Thumb指令
位宽为16位
3.ARM核的37个寄存器
寄存器:暂存数据的硬件,类似内存
寄存器分类:特殊功能寄存器和ARM寄存器
特殊功能寄存器:各种硬件控制器内部的寄存器,也就是之前课程常说的"一大堆寄存器",CPU核访问这类寄 存器都是通过地址指针的形式访问
ARM寄存器:仅仅存在于ARM核内部
CPU核访问内部的ARM寄存器通过名字(不区分大小写)
共37个ARM寄存器
ARM核37个寄存器:
31个通用寄存器:
r0,r1,r2,...r15
每一种工作模式下又有自己单独的寄存器
r15又称pc:永远只保存取指器要取的那条指令的内存存储地址
r14又称lr:永远只保存返回地址
r13又称sp:永远只保存栈指针
6个状态寄存器:
1个cpsr和5个spsr
cpsr又称当前程序状态寄存器,也就是保存
当前程序运行的状态
spsr又称备份程序状态寄存器,本质目的就是
为了保存cpsr的值
此时此刻务必画出37个寄存器的分布图!
详解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配置位I
=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的值就会随时随刻改变!
问:cpsr用于指示当前程序运算的状态,那么
spsr字面上说是备份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
4.ARM支持的数据类型
Byte:1字节
HalfWord:2字节
Word:4字节
DoubleWord:8字节
笔试题:考察内存对齐问题
struct A {
char a;
int b;
short c;
};
求:sizeof(struct A) =答案参见背面.
5.ARM支持大端和小端模式,默认为小端
X86是小端
Powerpc是大端
笔试题:编写程序,确定当前系统使用的是大端还是小端?
6.ARM汇编语法格式:
1.ARM汇编源文件以.s(.S)结尾
参考代码:
.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 @代码段的结束
问:何为"标签"?
答:标签类似C语言的函数名和变量名
到底是函数还是变量,关键看标签
里对应的内容:
如果标签里的内容是一堆代码,此标签就是函数名
如果标签里的内容是数值,此标签就是变量
7.切记:影响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
例子:
cmp r0, #4
cmpne r0, #10
moveq r1, #0
假设r0=4,CPU核执行三条指令的细节:
1.比较r0和4,本质做:运算结果=r0-4=4-4=0
运算结果为0,影响CPSR的Z,Z=1
2.当CPU核执行cmpne时,首先判断CPSR的Z位
是否为0,现在Z=1,条件不成立,所以cmp不执行
3.执行CPU核执行moveq时,首先判断CPSR的Z位
是否位1,现在Z=1,条件成立,所以执行mov
将0赋值给r1
假设r0=10,CPU核执行三条指令的细节:
1.比较r0和10,本质做:运算结果=r0-4=10-4=0
运算结果为6,影响CPSR的Z,Z=0
2.当CPU核执行cmpne时,首先判断CPSR的Z位
是否为0,现在Z=0,条件成立,所以cmp执行
3.比较r0和10,本质做:运算结果=r0-10=10-10=0
运算结果为0,影响CPSR的Z位,Z=1
3.执行CPU核执行moveq时,首先判断CPSR的Z位
是否位1,现在Z=1,条件成立,所以执行mov
将0赋值给r1
假设r0=250,CPU核执行三条指令的细节:
1.比较r0和4,本质做:运算结果=r0-4=250-4=246
运算结果为246,影响CPSR的Z,Z=0
2.当CPU核执行cmpne时,首先判断CPSR的Z位
是否为0,现在Z=0,条件成立,所以cmp执行
3.比较r0和10,本质做:运算结果=r0-10=250-10=240
运算结果为240,影响CPSR的Z位,Z=0
3.执行CPU核执行moveq时,首先判断CPSR的Z位
是否位1,现在Z=0,条件不成立,所以不执行mov
注意:记住常用的四个条件助记符:EQ/NE/CS/CC
1.I2C总线
面试题:谈谈对I2C总线的理解
面试题:谈谈对ARM裸板编程的理解
1.1.常见的几种硬件通信方式
1.2.I2C总线定义
画图
1.3.看图提三个问题
协议
1.4.I2C总线协议概念
1.5.举例子画图说明访问的过程
1.6.举例子画图说明配合
1.7.谈谈调试心得
1.8.以MMA8653三轴加速度传感器的访问为例
谈谈裸板编程的思路
1.用户需求分析
2.掌控硬件信息
粗看
位置
细看
原理图
画图
结论
处理器的手册
I2C控制器以及内部寄存器以指针的形式访问地址
BIT位含义
MMA8653的手册
片内寄存器不能以指针的形式访问,必须严格按照时序图访问
BIT位含义
3.按照裸板编程框架实现代码
谈谈裸板编程框架
顺便谈谈裸板程序的阅读
挑衅:"只要给我一套裸板程序,我就能够理顺程序的执行流程"
1.首先找链接脚本,确定
第一个运行的文件
运行的入口函数
运行的起始地址
2.如果没有链接脚本,看Makeifle
确定运行的第一个文件
第一个文件里指定入口函数
确定运行的起始地址
3.找到了入口函数,利用著名的源码阅读工具sourceinsight和ctags顺藤摸瓜,理顺代码的执行流程,
在阅读时,要将源码和原理图和芯片手册结合起来
4.下位机测试
*************************************************
*************************************************
*************************************************
*************************************************
*************************************************
2.ARM体系结构与编程
面试题:谈谈对ARM处理器的理解
2.1.首先交代常见的几种处理器架构
X86架构:
intel
amd
Powerpc架构:
飞思卡尔
DSP架构:
TI(达芬奇系列:处理器包含DSP核和ARM核)
FPGA架构:
xilinx(ZYNQ系列:处理器包含FPGA核和ARM核)
ARM架构:
华为(海思系列),小米(澎湃),全志(A系列)
MTK,英伟达
高通,TI,Atmel,博通,三星,飞思卡尔等
单片机系列:
51单片机,MSP430,STM32(低端ARM处理器)
"嵌入式处理器":把X86去掉,剩余的都是嵌入式处理器
2.2.何为"ARM",谈谈ARM的定义
ARM既可以认为是一款处理器架构,又可以认为是一家公司(ARM公司)。
ARM公司不生产具体的处理器,而是涉及ARM
做IP授权给各个生产处理器的厂家
例如:S5P6818处理器的CPU核就是ARM公司设计
而其他控制器由三星公司添加
CPU核又称ARM核!
2.3.谈谈ARM的版本划分
明确:ARM的版本仅仅指ARM核的版本(ARM公司定义)
ARM核大版本为:ARMV4/ARMV5/ARMV6/ARMV7/ARMV8
每一个大版本下又分若干个小版本(ARM核)
ARMV4:
小版本 具体的处理器
ARM720T S3C4510(三星)
ARM920T S3C2410(三星)
ARMV5:
Xscale PXA270(intel)
ARM10 S3C6410(三星)
ARMV6:
ARM11 S3C6440(三星)
ARMV7:
ARM-CORTEX-A8 S5PV210(三星)
ARM-CORTEX-A9
ARM-CORTEX-A15
ARM-CORTEX-M3/M0/M3 STM32(M3)主打低端
ARMV8:正式支持64位
ARM-CORTEX-A53 S5P6818(三星)
ARM-CORTEX-A57
2.4.谈谈ARM7(ARMV4)三级指令流水线
1.明确相关概念
"指令":给CPU核下发的命令,CPU核根据命令完成一个功能
例如:给CPU核发一个add指令,就是告诉CPU核做
数据的加法运算
"指令在哪里":指令就是存在于二进制文件中(shell.bin)
CPU核要想执行指令,首先将指令对应的
二进制文件加载到内存中,指令最终
存在于内存中,内存的访问以地址的执行访问
所以每一条指令也有对应的内存存储地址
所以CPU要想运行一条指令,首先从内存中
获取到指令
注意:32位系统:
CPU核工作在ARM状态下:一条指令的宽度为32位(4字节)
CPU核工作在THUMB状态:一条指令的宽度为16位(2字节)
2.CPU核运行一条指令的三级流水线为(仅做了解):
取指:CPU核中的取指器(硬件)从内存中读取
要运行的指令
解码:CPU核取完指令以后,这时候执行还不能
直接去运行(CPU核还不能识别),需要
解码器进行解码翻译
执行: 翻译完成,CPU核最终执行指令
总结:
一条指令CPU核最终运行需要三步:
取指F->解码D->执行E
画出一个三级流水线的操作示意图!
3.PC
PC是个寄存器,位宽为32位,类似监工
它是ARM核(CPU核)中的寄存器
它永远只保存取指器要取的那条指令对应的内存存储地址
例如:
内存存储地址 指令
0x48000000 add
0x48000004 sub
0x48000008 and
... ...
请问:当add指令被执行的时候,PC=?
答:当add执行的时候,取指器取and指令,那么PC=0x480000008
4.ARM7三级流水线特例之ldr指令
ldr指令功能:CPU核利用此指令能够从外设中加载数据到CPU核中
ldr指令流水线为五级:
取指F->解码D->执行E->访存M->写回W
说明:
访存:CPU核找外设地址
写回:CPU核一旦找到了外设地址,将外设的数据
加载到CPU核中
注意:ARM7的ldr指令在M和W的时候,后面的两条指令
的处理要延后两个周期
5.ARM7三级流水线特例之bl指令
bl指令的功能:CPU核执行bl指令,能够跳转到bl指令指定的一个
内存地址去运行(取指->解码->执行)
bl指令处理流水线需五级:
取指F->解码D->执行E->保存返回地址L->正式跳转A
说明:
保存返回地址L:CPU核跳转到bl指令指定的地址运行之前
先把返回地址(bl指令的下一条指令)进行
保存处理
正式跳转A:CPU核跑到bl执行指定的地址去运行
6.ARM7三级流水线特例之中断
中断定义:中断是计算机非常重要的一个机制
问:计算机中为什么有中断呢?
答:中断产生的根本原因就是CPU的数据处理
速度远远快于外设的数据处理速度
举例子说明中断:以CPU核读取UART接收缓冲区的数据为例
当CPU核读取UART接收缓冲区数据时,当CPU核发现接收
缓冲区没有数据,首先会考虑到采用轮训方式(死等)
判断接收缓冲区有没有数据到来,但这种操作方式
会让CPU核不能干其他事情,大大降低了CPU的利用率
此时此刻,一定要想到轮训的死对头中断方式操作UART
接收缓冲区:
当CPU核读取UART接收缓冲区数据时,当CPU核发现接收
缓冲区没有数据,CPU核此时去干别的事情(处理一个算法任务)
一旦将来接收缓冲区有数据到来,UART控制器会给
CPU发送一个中断电信号(嗨,数据到来了)
CPU一旦接收到了UART控制器发送的中断电信号
以后,CPU停止手头正在处理的事情(算法任务)
转去读取UART接收缓冲区的数据,读完以后,CPU
核继续去处理之前被打断的事情(算法任务)
这种CPU至少干两件事,大大提高了CPU的利用率
问:中断电信号的硬件处理是什么样呢?
答:以BT通过UART给CPU核发送数据'A'为例
1.当BT没有或者正在给CPU发送数据'A'时,
此时CPU核去读取数据,此时数据没有准备就绪
CPU核干其他的事情
2.一旦UART控制器将数据接收完毕,UART控制器
首先给中断控制器发送一个中断电信号
3.中断控制器接收到这个中断电信号以后
中断控制器硬件上做一番的判断
4.经过一番判断,中断控制器最终给CPU核发送
一个中断电信号,此中断电信号可以走FIQ
信号线也可以走IRQ信号线
如果是FIQ,此中断信号又称快速中断
如果是IRQ,此中断信号又称普通中断
5.CPU核一旦接收到FIQ或者IRQ中断信号
CPU核停止手头的工作转去处理接收到的
数据'A',处理完毕,CPU核继续处理原先被
打断的事情
CPU核接收到中断信号以后,开始处理中断,
那么中断处理流水线需四级:
切记:当CPU核正在执行某个执行时,如果CPU核
接收到中断信号,CPU核处理中断一定是
在当前执行执行完以后再去处理中断
解码中断DI->执行中断EI->保存返回地址L->正式跳转A
说明:
保存返回地址L:中断产生之前,CPU在别的函数中做事
中断到来,CPU核要跑另一个函数中执行
将来执行完毕,还要返回到原先被打断的
函数中继续执行,所以要想返回先
保存返回地址
2.5.ARM9(ARMV4)以后ARM核的五级流水线
1.ARM9以后的所有ARM核指令流水线一律采用五级
也就是将访存M和写回W给每一条指令都添加上
例如:
三级流水线:add:F->D->E
ldr:F->D->E->M->W
五级流水线:add:F->D->E->(M)->W
ldr:F->D->E->M->W
注意:add/sub/orr/eor/and等指令仅仅是在CPU核内部玩,
无需访问外设,所以无需访存M
但是访问M这个时间(位置)需要保留
画出一个五级流水线的处理示意图!
2.6.ARM编程模型(必考)
1.ARM核的7种工作模式
SVC管理模式
当系统复位或者软件执行swi指令,CPU核切换到此模式下
FIQ快速中断模式
外设给CPU核发送一个FIQ快速中断信号,CPU核切换到此模式下
IRQ中断模式
外设给CPU核发送一个IRQ普通中断信号,CPU核切换到此模式
Abort中止模式
当CPU核取指失败或者访存失败,CPU核进入此模式
Undef未定义指令模式
当CPU核执行一个不认识的指令(lisi),CPU核进入此模式
System系统模式
User用户模式
System和User一样,CPU核正常运行的情况下,CPU核
要不在System模式要不在User模式,linux系统
下,当CPU核处理一个进程时,对应的CPU核为User模式
2.ARM核的两种工作状态
ARM状态
ARM指令
位宽为32位
Thumb状态
Thumb指令
位宽为16位
3.ARM核的37个寄存器
寄存器:暂存数据的硬件,类似内存
寄存器分类:特殊功能寄存器和ARM寄存器
特殊功能寄存器:各种硬件控制器内部的寄存器,也就是之前课程常说的"一大堆寄存器",CPU核访问这类寄 存器都是通过地址指针的形式访问
ARM寄存器:仅仅存在于ARM核内部
CPU核访问内部的ARM寄存器通过名字(不区分大小写)
共37个ARM寄存器
ARM核37个寄存器:
31个通用寄存器:
r0,r1,r2,...r15
每一种工作模式下又有自己单独的寄存器
r15又称pc:永远只保存取指器要取的那条指令的内存存储地址
r14又称lr:永远只保存返回地址
r13又称sp:永远只保存栈指针
6个状态寄存器:
1个cpsr和5个spsr
cpsr又称当前程序状态寄存器,也就是保存
当前程序运行的状态
spsr又称备份程序状态寄存器,本质目的就是
为了保存cpsr的值
此时此刻务必画出37个寄存器的分布图!
详解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配置位I
=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的值就会随时随刻改变!
问:cpsr用于指示当前程序运算的状态,那么
spsr字面上说是备份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
4.ARM支持的数据类型
Byte:1字节
HalfWord:2字节
Word:4字节
DoubleWord:8字节
笔试题:考察内存对齐问题
struct A {
char a;
int b;
short c;
};
求:sizeof(struct A) =答案参见背面.
5.ARM支持大端和小端模式,默认为小端
X86是小端
Powerpc是大端
笔试题:编写程序,确定当前系统使用的是大端还是小端?
6.ARM汇编语法格式:
1.ARM汇编源文件以.s(.S)结尾
参考代码:
.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 @代码段的结束
问:何为"标签"?
答:标签类似C语言的函数名和变量名
到底是函数还是变量,关键看标签
里对应的内容:
如果标签里的内容是一堆代码,此标签就是函数名
如果标签里的内容是数值,此标签就是变量
7.切记:影响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
例子:
cmp r0, #4
cmpne r0, #10
moveq r1, #0
假设r0=4,CPU核执行三条指令的细节:
1.比较r0和4,本质做:运算结果=r0-4=4-4=0
运算结果为0,影响CPSR的Z,Z=1
2.当CPU核执行cmpne时,首先判断CPSR的Z位
是否为0,现在Z=1,条件不成立,所以cmp不执行
3.执行CPU核执行moveq时,首先判断CPSR的Z位
是否位1,现在Z=1,条件成立,所以执行mov
将0赋值给r1
假设r0=10,CPU核执行三条指令的细节:
1.比较r0和10,本质做:运算结果=r0-4=10-4=0
运算结果为6,影响CPSR的Z,Z=0
2.当CPU核执行cmpne时,首先判断CPSR的Z位
是否为0,现在Z=0,条件成立,所以cmp执行
3.比较r0和10,本质做:运算结果=r0-10=10-10=0
运算结果为0,影响CPSR的Z位,Z=1
3.执行CPU核执行moveq时,首先判断CPSR的Z位
是否位1,现在Z=1,条件成立,所以执行mov
将0赋值给r1
假设r0=250,CPU核执行三条指令的细节:
1.比较r0和4,本质做:运算结果=r0-4=250-4=246
运算结果为246,影响CPSR的Z,Z=0
2.当CPU核执行cmpne时,首先判断CPSR的Z位
是否为0,现在Z=0,条件成立,所以cmp执行
3.比较r0和10,本质做:运算结果=r0-10=250-10=240
运算结果为240,影响CPSR的Z位,Z=0
3.执行CPU核执行moveq时,首先判断CPSR的Z位
是否位1,现在Z=0,条件不成立,所以不执行mov
注意:记住常用的四个条件助记符:EQ/NE/CS/CC
阅读全文
0 0
- day08 ARM体系结构与编程、流水线
- ARM:ARM体系结构与编程、ARM指令流水线、ARM编程模型基础
- ARM体系结构与编程
- ARM体系结构与编程
- ARM体系结构与编程 书
- ARM体系结构与编程作业
- ARM体系结构与编程笔记
- ARM体系结构与编程-2
- ARM体系结构与编程-3
- ARM体系结构与编程-4
- ARM体系结构与编程-5
- ARM体系结构与编程笔记
- ARM体系结构(二)——流水线
- 【嵌入式Linux+ARM】ARM体系结构与编程(ARM概述)
- 【嵌入式Linux+ARM】ARM体系结构与编程(ARM汇编指令)
- 《ARM体系结构与编程》中的严重错误
- ARM体系结构与编程学习(一)
- ARM体系结构与编程学习(二)
- 后台常见报错
- Tomcat单独可以启动,在Eclipse中启动访问404
- Ubuntu14.04 启动terminal进入命令行之前有log信息输出
- Android读写SD卡中的txt文件
- 微信获取code和openid
- day08 ARM体系结构与编程、流水线
- 整形数转换成字符串
- Java线上应用故障排查之一:高CPU占用
- ubuntu终端命令
- B2Ctt商城01
- day09 ARM汇编指令
- Struts2 重定向 乱码解决方案
- java实现单向链表的常用操作
- Java线上应用故障排查之二:高内存占用