(eg:ARM 920t 这个cpu)
CPU中: ALU-运算器
R0寄存器 (一般有几十个,2440中R0~R12)
PC:程序计数器 指向正在执行的下下条指令。默认值为0,默认做自加操作。
LR:链接寄存器 (/链接返回寄存器)保存函数的返回地址
----LR栈的结构??----
空栈 --先压栈再移动指针 / 满栈 --先移动指针再压栈
指针指的都是空的地址 指针指的一直都是有内容的地址
+++我们使用的是 满减 的栈结构
SP:栈指针寄存器 指向栈顶
CPSR:当前程序状态寄存器 进借位、结果为负、结果为零、中断使能、大小端配置、工作模式
PSR:程序状态寄存器
SPSR:保存程序状态寄存器
Cache:缓存 I(指令) D(数据) --- 分别16KB
冯诺依曼 和 哈佛
数据跟指令存放在一起 数据和指令是分开的
Cache命中 : cache在内存先拿数据(对于重复的数据只读一次),
CPu在cache区读取数据的时候 读的速度比 CPU读取内存数据更快
MMU: 内存管理单元 虚拟地址到物理地址的切换
每次访问会先访问页表
===================================================================
SOC(片上系统 system on chip) S3C2440
:
CPU:中央处理单元
MCU: 微控制器
MPU:微处理器
SOC:片上系统
DSP:数字信号处理
FPGA:现场可编程门阵列
ARM处理器最新发展:
Cortex-A 消费类电子---低功耗
Cortex-R 实时性 --- 航空航天军工 汽车电子
Cortex-M 高性能 --- 偏控制 eg:STM32
ARM ---> CPU IP
编译器的过程;
半导体器件:
TTL : 高电平 > 2.4V 低电平 < 0.4V
钽电容 带标记的是正极 其他都是带标记的是负极
寄存器组织概要:
有 37 个寄存器 user中 16 + cpsr
指令和代码一般都是4字节对齐的
异常处理:
当异常产生时,先拷贝CPSR 到对应的工作模式下的SPSR中
设置适当的CPSR位:
改变处理器的状态进入ARM态
改变处理器模式进入相应的异常模式
设置中断禁止位禁止相应中断
保存返回地址到LR对应的MODE
设置PC为相应的异常向量
返回时,异常处理需要:
从SPSR------mode 恢复CPSR
从LR_mode恢复PC
Note:这些操作只能在ARM态执行。
处理器的七种工作模式
User :用户模式 //非特权模式,大部分任务执行在这种模式
FIQ:快中断模式 //当一个高优先级(fast)中断产生时将会进入这种模式
IRQ:中断模式 //当一个低优先级(normal)中断产生的时候将进入这个模式
Supervisor:SVC/管理模式 //当复位或软中断指令执行的时候将进入这种模式
Abort:中止模式 //当存取异常时进入这种模式
Undef: 未定义模式 //当执行未定义指令时会进入这种模式
System:系统模式 //使用和User模式相同寄存器集的特权模式
CPRC程序状态存储器中有条件位,中断禁止位,Mode位等重要的位存储
ARM汇编
指令集(版本):armV4
流水线:
三级流水线----->程序执行过程: 预取 译码 执行
最佳流水线:
1 2 3 4 5 6
预取 译码 执行
预取 译码 执行
预取 译码 执行
预取 译码 执行
。。。。。。
总线:地址总线/数据总线/控制总线.
<opcode>{<cond>}{S}<Rd>,<Rn>{,<operand2>}
//凡是带大括号的都可以省略
ARM指令集分为六大类
数据处理指令:
RSB-----反向减法
BIC --- 位清零 在后面#设置为1的地方清0
eg: BIC r1, #0xF //把r1后四位清零
MVN --- 按位取反之后放进去
ADD ---相加
SUB ---相减
AND --- 按位与
ORR ---按位或
EOR --- 异或 相同为0 不同为1
MOV --- 赋值
ADC --- 用进借位的指令相加
(当进借位有值的时候会一起加) //注意CPSR位
eg:adc r5,r1,r3 //此时r1+r3 的结果会加上+C 放在r5
//若是adc 运算完不清C位 若是adcs 运算完会清掉C位
CMP ---- 比较
cmp r0,r1
//比较结果放在CPSR的位中
立即数
一个数字(或者按位取反后)或将其循环右移偶数位后所有的1能放在低8位中
bl 带链接返回的跳转
ldr sp, =0x40001000 //专门加载地址到一个寄存器
入栈指令: STMFD (push)
出栈指令: LDMFD (pop)
eg:
STMFD sp! {r4-r7,lr}
//! 会自动变更地址
函数使用的时候需要保护现场和恢复现场
C语言和汇编的混合编写:
import myadd //声明 使用外部函数 相当于extern
bl myadd //调用另外C中的函数
preserve 8 //8字节对齐的指令 在汇编头中写这个即可
函数传参规则:
函数传参的时候用的是r0~r3前四个寄存器--->分别对应传入函数的第一二三四位参数的值
超过4个的参数使用栈来进行传递
返回值:返回值存放在R0中
要想汇编的函数被其他文件调用需要 先用export 声明函数
栈中存储的数据有什么: 局部变量 函数的参数 函数的返回地址
^带模式的恢复现场
在恢复现场的时候在最后加上^
ldmfd sp!, {r4-r12,pc}^ 这个^就会恢复到之前存储这个数据的现场
获得swi #xxx 这个xxx的数字是多少的方法?
stmfd sp!,{r4-r12,lr}
sub r0,lr,#0x4
ldr r1,[r0] ;获取swi这个数字是多少
bic r0,r1,#(0xff<<24)
ldmfd sp!,{r4-r12,pc}^