第3章Cortex-A8处理器编程
1. ARM编程简介
• 在嵌入式系统开发中,目前使用的主要编程语言是C和汇编。很多地方,例如开机时硬件系统的初始化,包括CPU状态的设定、中断的使能、主频的设定、以及RAM的控制参数及初始化等都使用汇编语言。汇编语言是和CPU的指令集紧密相连的,作为涉及底层的嵌入式系统开发,汇编语言编程不可或缺的重要方法。
• ARM嵌入式系统程序设计和所使用的ARM微处理器资源密切相关。只有了解ARM微处理器的工作模式、状态、存储器组织、寻址方式,并且掌握ARM的指令系统,才有可能写出适用的ARM程序。
2. Cortex-A8处理器模式和状态
处理器模式
改变处理器的模式:软件控制 外部中断 异常处理
用户模式:正常模式,不能访问某些被保护的系统资源,不能改变模式,除非发生异常
特权模式:除用户模式,自由访问系统资源和改变模式
系统模式:不允许异常进入,与用户模式有相同的寄存器,不受用户模式限制
处理器状态
Cortex-A8处理器有3种操作状态,这些状态由CPSR寄存器的T位和J位控制。
l ARM状态:执行32位字对齐的ARM指令,T位和J位为0。
l Thumb状态:执行16位或32位半字对齐的Thumb2指令,T位为1,J位为0。
l ThumbEE状态:执行为动态产生目标而设计的16位或32位半字对齐的Thumb2指令集的变体。T位和J位为1。
处理器的操作状态可以在以下几种状态间转换:
l ARM状态和Thumb状态之间转换
使用BL和BLX指令,并加载到PC。
l Thumb状态和ThumbEE状态之间转换
使用ENTERX指令和LEAVEX指令。
异常会导致处理器进入ARM状态或Thumb状态。一般情况,当退出异常处理时,处理器会恢复原来的T位和J位的值。
3. Cortex-A8存储器组织
1数据类型
Cortex-A8支持以下数据类型:
1)双字,64位;
2)字,32位(占用4个字节);
3)半字,16位(占用两个字节);
4)字节,8位。
2存储格式
Cortex-A8处理器支持小端格式和字节不变的大端格式。此外,处理器还支持混合大小端格式(既有大端格式又有小端格式)和非对齐数据访问。对指令的读取,则总是以小端格式操作。
ARM的存储组织结构:
32位长的地址,它把存储器看成是0地址开始的字节的线性组合,即一个地址对应于一个存储字节,其范围是232个字节(8位二进制数)。
3寄存器组
Cortex-A8处理器总共有40个32位长的寄存器。
l 33个通用寄存器。
l 7个状态寄存器:
——1个CPSR(Current Programs Status Register,当前程序状态寄存器);
——6个SPSR(Saved Program Status Register,备份程序状态寄存器)。
这些寄存器不能同时访问,处理器状态和操作模式决定了哪些寄存器对编程者是可用的。
l 未分组的通用寄存器R0—R7
16个数据寄存器中R0--R7是未分组的通用寄存器,用来保存数据和地址。
l 分组通用寄存器R8—R15,处理器模式决定物理寄存器
——R8—R12寄存器:快速中断及其他模式两组;
——R13,R14寄存器:分7组,用户和管理模式共用;
R13:又称SP,堆栈指针
R14:又称LR,链接寄存器
——R15:又称PC,程序计数器,所有模式共用;
l 当前状态寄存器CPSR:所有模式共用;
分组的状态保存寄存器SPSR:6个异常模式对应。
状态寄存器
当前程序状态寄存器CPSR和6个状态保存寄存器SPSR主要功能如下:
l 保存最近执行的算术或逻辑运算的信息;
l 控制中断的允许或禁止;
l 设置处理器操作模式。
4 异常
异常是系统处理外部异步事件的方法。
异常出现后处理器强制从异常类型所对应的固定存储器地址开始执行程序,这些存储器地址称为异常向量表。
异常的进入
(1)将下一条指令的地址保存在相应的LR寄存器中。
(2)将CPSR复制到相应的SPSR中。
(3)迫使CPSR模式位M[4:0]的值设置成对应的异常模式值
(4)迫使PC从相关的异常向量取下一条指令。
(5)用户可以设置中断禁止位来阻止或打开异常嵌套。如果在异常发生时处理器是在Thumb状态下,那么当用中断向量地址加载PC时,自动切换进入ARM状态。
异常的退出:
(1)将LR寄存器的值减去相应的偏移量(偏移量根据异常的不同而不同),送到PC中。
(2)将SPSR复制回CPSR中。
(3)清除中断禁止位标志。
5 寻址方式
寻址方式是根据指令中给出的地址码字段来寻找真实操作数地址的方式
寄存器寻址 ADD R0,R1,R2 ;R0=R1+R2
立即寻址 MOV R0,#0xff00 ;R0ß0xff00
寄存器移位寻址 ADD R3,R2,R1,LSL #3 ;R3=R2+8×R1
寄存器间接寻址 SWP R1,R1,[R2] ;R0与[R1]数值进行交换
变址寻址 STR R1,[R0,#-2] ;[R0-2]ßR1
块拷贝寻址 STMIA R0!,{R1-R7}
多寄存器寻址 LDMIA R1,{R0,R2,R5} ;R0=[R1],R2=[R1+4],R5=[R1+8]
;由于传送的数据项总是32位的字,基址R1应该字对准。
相对寻址 目标地址 = pc 当前值 + 指令给出的标号偏移地址
堆栈寻址 STMFD SP!,{R1-R7,LR} ;将R1-R7,LR入栈,满递减堆栈
典型堆栈及其含义
向上生长,又称递增堆栈,即地址向高地址方向生长。
向下生长,又称递减堆栈,即地址向低地址方向生长。
满堆栈,堆栈指针指向最后压入堆栈的有效数据项。
空堆栈,堆栈指针指向下一个数据项放入的空位置。
6. 指令系统
基本格式
第2个操作数
8位位图数据,即一8位的常数通过循环右移偶数位得到
条件码
存储器访问指令
LDR和STR指令应用
1.加载/存储字和无符号字节指令
LDR R2,[R5] ;将R5指向地址的字数据存入R2
STR R1,[R0,#0x04] ;将R1的数据存储到R0+0x04地址
LDRB R3,[R2],#1 ;将R2指向地址的字节数据存入R3,R2=R2+1
STRB R6,[R7] ;将R7指向地址的字节数据存入R6
2.加载/存储半字和有符号字节指令
LDRSB R1,[R0,R3] ;将R0+R3地址上的字节数据存入R1,高24位用符号扩展
LDRH R6,[R2],#2 ;将R2指向地址的半字数据存入R6,高16位用0扩展,读出后,R2=R2+2
STRH R1,[R0,#2]! ;将R1的半字数据保存到R0+2地址,
;只修改低2字节数据,R0=R0+2
多寄存器存取 堆栈操作
数据处理指令(数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。所有ARM数据处理指令均可选择使用S后缀,并影响状态标志):
数据传送指令
算术逻辑运算指令;
比较指令
状态寄存器指令
读:MRS指令可以对状态寄存器CPSR和SPSR进行读操作
MRS R1,CPSR ; 将CPSR状态寄存器读取,保存到R1中
写: