一、RAM分类
(一)sram(static ram)
用晶体管存储0、1;
速度快,成本高,存储密度低;
应用于单片机。
(二)dram(dynamic ram)动态存储
用电容充放电存储0,1;
功耗大,需要外接(外接刷新电路,电路复杂(定期向存储1的补充电荷)),读写速度低于sram,成本低,存储密度大;
多应用与高端Soc。
(三)sdram(synchronous dram)
增加了同步电路,提高dram的数据读写速度(dram升级版)。
(四)ddr ram(ddr sdramldouble data rate sdram)
为sdram的下一代;双倍速(双数据速率)
(五)iram(internal ram)
注意iram并非是真正意义上的某种ram,通常iram就是 sram,它通常存在于Soc内部,所以被称为iram(Soc内部直接封装好在芯片内部的sram)
二、ROM分类
注意:flash闪存中,nor flash是可被CPU直接寻址的,用于存放系统启动程序;
nand flash不可被CPU寻址,用于存放额外文件,如文件视频等
ARM的指令集:
ARM指令集(32bit)
Thumb指令集(16bit)
扩展:嵌入式运行Linux操作系统
在嵌入式中 nor flash 存放的是系统的启动代码(一段程序),设置nor flash 的第一个字节的地址为零,PC上电后会自动清零,程序从地址0开始执行。nand flash 多用来存放文件,典型应用eMMc(电多媒体卡)。
把操作系统包括Linux本身的执行代码、根文件、应用程序、命令统统存放在eMMc中。在nor flash中装入一段启动代码(该代码最先被运行),运行起来后自动初始化eMMc,把eMMc中的操作系统拷到ddr ram中,最终操作系统在ddr ram中运行
三、ARM处理器工作模式(kernel)
(一)Cortex A7的9种基本工作模式
(1)User:非特权模式:大部分任务执行在这种模式
(2)FIQ:快速中断请求模式:当一个高优先级(fast)中断产生时将会进入这种模式
(3)IRQ:中断请求模式:当一个低优先级(normal)中断产生时将会进入这种模式
(4)Supervisor(SVC):软中断:当复位或软中断指令执行时将会进入这种模式
(5)Abort:终止模式:当存取异常时将会进入这种模式
(6)Undef:指令未定义模式:当执行未定义指令时会进入这种模式
(7)System:是一种特权工作模式,具有与 User 模式相同的寄存器视图,但拥有 最高特权级别;
(8)Cortex-A特有模式
(9)Monitor:监视模式:是为了安全而扩展出的用于执行安全监控代码的模式;也是一种特权模式。
四、寄存器组织概要图(查询重点)
- 不同的工作模式下,各自管理不同的栈(SP寄存器和LR寄存器);
五、CPSR程序状态寄存器
1、N,V,C,Z位
注:汇编指令的s后缀,几乎所有的汇编指令都可以在指令后面加上s后缀,s后缀的含义是在指令执行过程中会更新cpsr寄存器的N,V,C,Z位
N:在结果是有符号的二进制补码情况下,如果结果为负数,则N=1;如果结果为非负数,则N=0
Z:如果结果为0,则Z=1;如果结果为非零,否则Z=0
C:是针对无符号数最高有效位向更高位进位时C=1;减法中运算结果的最高有效位从更高位借位时C=0
V:该位是针对有符号数的操作,会在下面两种情形变为1,两个最高有效位均为0的数相加,得到的结果最高有效位为1;两个最高有效位均为1的数相加,得到的结果最高有效位为0;除了这两种情况以外V位为0
六、异常处理
(一)异常发生时底层运行过程
(二)异常模块
注意:
- 中断的本质也是一种异常;
- 异常向量表:用于存储不同类型异常发生时,处理器跳转到特定的异常处理程序的地址;————用于存储不同类型异常发生时处理器跳转地址的特定内存区域,就是由操作系统初始化并设置基址寄存器指向的异常向量表(EVT)。这个表的每个条目都存储着对应异常处理程序的起始地址。
在同一种中断中,同一模式下的中断不能被再次被直接打断
FIQ中断
IRQ中断
(保留)
Data Abort(数据存储异常)————对RAM的访问发生错误
Prefetch Abort(预取失败异常)————指令预取阶段内存访问失败触发
Software Interrupt(软中断异常)————软件中断(任务切换),多任务的并发靠底层的软中断实现
Undefined Instruction(未定义指令异常)
Reset(复位异常)
七、RAM指令学习
(一)MOV指令
加载12位立即数到寄存器或转移一个寄存器的值到另外一个寄存器;
1、MOV{S}<c> <Rd>, #<const>
eg:mov r0, #2 ;加载立即数2到寄存器r0
2、MOV{S}<c> <Rd>, <Rm>
eg:mov r1, r0 ;将r0寄存器的值加载到r1
注:大多数指令的格式为opcode rd, rn ,rm,其中,rd是目标寄存器,rn是第一操作数
3、MOV{S}<c> <Rd>, <Rm>,lsl r1
MOV r1, r0,lsl r1://将r0中的值左移r1位放入r1寄存器中;
- ASR算术右移
- LSL逻辑左移
(二)MVN指令————按位取反
eg: mvn r3, #1 ;1按位取反放入r3寄存器中,0xFFFFFFFE
注:MOV指令用不了寄存器会替换为MVN指令
(三)ADD指令————加法
add指令常用的两种方式:
1、ADD{S}<c> <Rd>, <Rn>, #<const>
“将Rn中的值和const加起来装在Rd中”
2、ADDS}<c> <Rd>, <Rn>, <Rm>{, <shift>}
(四)SUB指令——减法指令
1、SUB{S}<c> <Rd>, <Rn>, #<const>
将Rn减去const中的数,结果存放在rd中
2、SUB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
(五)立即数
立即数:相当于汇编中的常量,前加#
1、判断立即数的三个条件(以12为立即数为例)
1、如果某个数的数值范围是0~0xFF之间,那么这个数一定是立即数;
2、把某个数展开成2进制,这个数的最高位1至最低位1之间的二进制数序列的位数不能超过8位;
3、这个数的二进制序列凑够8位之后的的右边必须为偶数个连续的 0
2、原因
这是因为ARM中将这 12bits 分为 8bit 常数(0~255)和 4bit 循环右移位值(0~15)
8bit 常数范围(0~255),位移的步进值是以2为单位(即实际位移 2 * rotate 位),可以表示循环有以(0~30)偶数位: 0、2、4、6、8、10、12、14、16、18、20、22、24、26、28、30。在实际存储这个数值的时候,要想办法把这个数压缩到这12位中去。压缩的方法就是找一个数,这个数必须是一个8bit数,之后循环右移2 * rotate位。如果能找打这个数,那么待保存的数就是立即数,否则就不是。
(六)LDR寄存器加载指令
1、LDR{<c>}{<q>} <Rt>, <label> ;
如ldr r0, =0x2FAB4
ldr指令多用于从ram中将一个32位的字数据传送到目的寄存器中
2、LDR<c> <Rt>, [<Rn>{, #+/-<imm12>}]
如:LDR R0,[R1,#4]
;将内存地址为R1+4的字数据读入寄存器R0,这里的#4作为12位立即数是可以省略的
3、LDR<c> <Rt>, [<Rn>], #+/-<imm12>
如:ldr r0, [r1], #8 ;将内存地址R1的字数据读入r0,之后r1+8
4、LDR<c> <Rt>, [<Rn>, #+/-<imm12>]!
如:LDR R0,[R1,#8] ! ;将存储器地址为R1+8的字数据读入寄存器R0,并将新地址R1+8写入R1。
(七)STR指令(写入)
str 将数据存入地址中
如上图中,将r1的内容,写入r0+4的地址
(八)BIC指令(指定位清零)
BIC{S}<c> <Rd>, <Rn>, #<const>
将rn中的字数据const为1的比特清零,把结果放入rd
eg:mov r0, 0xFFFFFFFF
bic r0, r0, #3;立即数哪些位为1就清掉
r0数据:0xFFFFFFFC
bic r0, r0, #(0x1F << 8);连续5位清0
eg:
原数: 1111 1111
const中的数: 0000 0011
bic之后的数: 1111 1100
(九)ORR指令(指定位置1)
ORR{S}<c> <Rd>, <Rn>, #<const>
eg:mov r0, #0
orr r0, r0, #5;立即数带1的比特位置1
orr r0, r0, #(1<< 9);第9位置1
eg:
原数: 0000 0000
const中的数: 0000 0011
bic之后的数: 0000 0011
(十){s}
作用:加s影响CPSR寄存器
eg:mov r0, #0xFFFFFFFF;按有符号数算为-1
adds r2, r0, #0
adds影响CPSR寄存器,CPSR寄存器的N置1(因为结果为负)
mov r0, #0xFFFFFFFF
adds r1, r0, #1
上面的操作会导致Z,C置位,这是因为结果为0,并且从无符号数角度来看,已经从最高位向更高位进位了
mov r0. #0x7FFFFFFF
adds r1, r0, #1
会造成N位和C位置位,这是因为计算结果0x80000000最为位为1,代表负数,并且 从有符号角度来看,把一个整数加成了负数。
汇编指令的s后缀,几乎所有的汇编指令都可以在指令后面加上s后缀,s后缀的含义是在指令执行过程中会更新cpsr寄存器的N,V,C,Z位
N:在结果是有符号的二进制补码情况下,如果结果为负数,则N=1;如果结果为非负数,则N=0
Z:如果结果为0,则Z=1;如果结果为非零,否则Z=0
C:是针对无符号数最高有效位向更高位进位时C=1;减法中运算结果的最高有效位从更高位借位时C=0
V:该位是针对有符号数的操作,会在下面两种情形变为1,两个最高有效位均为0的数相加,得到的结果最高有效位为1;两个最高有效位均为1的数相加,得到的结果最高有效位为0;除了这两种情况以外V位为0
(十一)<c>自选地增加执行条件
例如:movcs r0, #100;表示只有在C位置位的情况下才能把100加载入r0,这样的话就可以非常方便地实现指令的有条件执行。
(十二)cmp指令
CMP比较指令用于比较两个寄存器的值或者比较一个寄存器和立即数的值,其原理是对待比较的两个数求差,看结果是否为0,这个指令会无条件修改N,V,C,Z位。
练习
1、从r0, r1代表的两个有符号数中找到较大值放入r2寄存器
2、找出三个数的最大值
;三位数找最大
;cmp r0, r1
;blt less
;great
;mov r2, r0
;b cmp1;less
;mov r3, r1;cmp1
;cmp r3, r2
;bge finished
;mov r3, r2
(十三)跳转指令b
b指令类似c语言的goto语句,能够实现无条件跳转。跳转时需要一个lable,表示要跳转到什么地方去 ;
指令b本质是往PC里填了一个数, b loop 相当于 ldr pc, =loop
练习1:实现从0加到100的和
1、while循环
2、do while 循环
练习2:填充数组值到指定地址的空间
ldr r0, =0x40000000
mov r1, #0
mov r2, #1loop
cmp r1, #10
bge finished
str r2, [r0], #4
add r2, r2, #1
add r1, r1, #1
ldr pc, =loop ;b loop
finished
b finished
end