目录
(四)ddr ram(ddr sdramldouble data rate sdram)
(二)prom(programmable rom)可编程rom
(三)eprom(erasable prom)可擦写prom
(四)eeprom(electically eprom)电可擦写可编程rom
1、从r0, r1代表的两个有符号数中找到较大值放入r2寄存器
一、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分类
(一)rom非易失性存储器
最早的rom在出场时写入数据,之后无法更改。
(二)prom(programmable rom)可编程rom
出场后能够让用户写入一次数据,例如cdrom。
(三)eprom(erasable prom)可擦写prom
出场后可以擦除数据再次写入, 但需要特殊的设备,如紫外光等。
(四)eeprom(electically eprom)电可擦写可编程rom
无需专用设备就可以擦写,编程。
(五)flash闪存,新一代非易失性存储器
1、nor flash(或非falsh)
可直接被CPU寻址(每个字节都有独一无二的地址)
2、nand flash(与非falsh)
不可被COU寻址,每个字节不可被寻址(用flash控制器可以访问)
扩:eMMc(电多媒体卡)
本质就是nand,也就是SD卡,不同之处:SD卡可拔可插,eMMc可直接焊在板子上。
扩展:嵌入式运行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种基本工作模式
(一)User:非特权模式
大部分任务执行在这种模式
(二)FIQ:快速中断请求模式
当一个高优先级(fast)中断产生时将会进入这种模式
(三)IRQ:中断请求模式
当一个低优先级(normal)中断产生时将会进入这种模式
(四)Supervisor(SVC):软中断
当复位或软中断指令执行时将会进入这种模式
(五)Abort:终止模式
当存取异常时将会进入这种模式
(六)Undef:指令未定义模式
当执行未定义指令时会进入这种模式
(七)System
使用和User模式相同寄存器集的特权模式
(八)Cortex-A特有模式
(九)Monitor:监视模式
是为了安全而扩展出的用于执行安全监控代码的模式;也是一种特权模式。
四、ARM寄存器
五、寄存器组织概要图(查询重点)
注:PC所有模式公用;
不同的工作模式下,各自管理不同的栈(SP和LR);
六、CPSR程序状态寄存器
1、Mode位
2、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
3、E位
E位:大小端控制位(默认小端)
七、异常处理
(一)异常发生时底层运行过程
(二)异常模块
FIQ中断
IRQ中断
(保留)
Data Abort(数据存储异常):对RAM的访问发生错误
Prefetch Abort(预取失败异常):指令预取阶段内存访问失败触发
Software Interrupt(软中断异常):软件中断(任务切换),多任务的并发靠底
层的软中断实现
Undefined Instruction(未定义指令异常)
Reset(复位异常)
(三)偏移量与异常向量表
偏移量:异常函数处理的入口地址;
异常向量表:用于存储不同类型异常发生时,处理器跳转到特定的异常处理程序的地址;
八、ARM指令
(一)查手册
A8.8:所有指令列表
(二)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是第一操作数
寄存器。
(二)MVN指令
eg: mvn r3, #1 ;1按位取反放入r3寄存器中,0xFFFFFFFE
注:MOV指令用不了寄存器会替换为MVN指令
(三)ADD指令
add指令常用的两种方式:
1、ADD{S}<c> <Rd>, <Rn>, #<const>
2、ADDS}<c> <Rd>, <Rn>, <Rm>{, <shift>}
(四)SUB指令
1、SUB{S}<c> <Rd>, <Rn>, #<const>
2、SUB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
(五)立即数
立即数:相当于汇编中的常量,前加#
1、判断立即数的三个条件(以12为立即数为例)
1、如果某个数的数值范围是0~0xFF之间,那么这个数一定是立即数;
2、把某个数展开成2进制,这个数的最高位1至最低位1之间的二进制数序列的位数不能超过8位;
3、这个数的二进制序列凑够8位之后的的右边必须为偶数个连续的 0
2、举例
0x234 = 0000 0000 0000 0000 0000 0010 0011 0100
最高位1至最低位1之间的二进制数序列:1000 1101没有超过8位
末尾1的右边有2个0,所以0x234是立即数
0x3f4 = 0000 0000 0000 0000 0000 0011 1111 0100
最高位1至最低位1之间的二进制数序列:1111 1101 从第一个1开始到最后一个1之间没有超过8位
末尾1的右边有2个0,所以0x3f4是立即数
0x132 = 0000 0000 0000 0000 0000 0001 0011 0010
最高位1至最低位1之间的二进制数序列:1001 1001 从第一个1开始到最后一个1之间没有超过8位
末尾1的右边有1个0,不满足第二条,所以0x132不是立即数
0x7f8 = 0000 0000 0000 0000 0000 0111 1111 1000
最高位1至最低位1之间的二进制数序列:1111 1111从第一个1开始到最后一个1之间没有超过8位
末尾1的右边有3个0,不满足第二条,所以0x7f8不是立即数
0xfab4 = 0000 0000 0000 0000 1111 1010 1011 0100
最高位1至最低位1之间的二进制数序列:0011 1110 1010 1101 从第一个1开始到最后一个1之间超过8位,不满足条件1,所以这个数不是立即数
3、原因
这是因为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
(九)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
(十){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