本章节主要介绍ARM 处理器的基本程序设计方法,包含ARM 指令实验,Thumb 指令实验和ARM 处理器工作模式实验。
4.1 ARM 指令实验
4.1.1 实验说明
实验目的: 透过实验掌握ARM 组译指令的使用方法。
实验设备: 硬件使用PC 主机,软件使用Embest IDE 2003 整合开发环境,Windows 98/2000/NT/XP。
实验内容: 使用简单ARM 组译指令,操作寄存器和内存区作互相的数据交换。
4.1.2 实验原理
ARM 处理器共有37个寄存器:31个通用寄存器,包括程序计数器(PC)。这些寄存器都是32 位的。6个状态寄存器。这些寄存器也是32 位的,但是只是使用了其中的12 位。
ARM 通用寄存器
通用寄存器(R0~R15)可分为3 类:
不分组寄存器R0~R7;
分组寄存器R8~R14;
程序计数器R15。
1)不分组寄存器R0~R7
R0~R7 是不分组寄存器。这意味着在所有处理器模式下,它们都存取一样的32 位寄存器。它们是真正的通用寄存器,没有架构所隐含的特殊用途。
2)分组寄存器R8~R14
R8∼R14 是分组寄存器。它们存取的物理寄存器取决于当前的处理器模式。若要存取特定的物理寄存器而不依赖当前的处理器模式,则要使用规定的各字。
寄存器R8~R12 各有两组物理寄存器:一组为FIQ 模式,另一组为除了FIQ以外的所有模式。寄存器R8~R12 没有任何指定的特殊用途。只是使用R8~R14来简单地处理中断。寄存器R13,R14 各有6 个分组的物理寄存器。1 个用于用户模式和系统模式,其它5 个分别用于5 种异常模式。寄存器R13 通常用做堆迭指标,称为SP。每种异常模式都有自己的R13。寄存器R14 用作子程序链接寄存器,也称为LR。
3) 程序计数器R15
寄存器R15 用做程序计数器(PC)。程序状态寄存器在所有处理器模式下都可以存取当前的程序状态寄存器CPSR。CPSR 包含条件码标志位,中断禁止位,当前处理器模式以及其它状态和控制信息。每种异常模式都有一个程序状态保存寄存器SPSR。当例外出现时,SPSR 用于保留CPSR的状态。
CPSR 和SPSR 的格式如下:
|
31 |
30 |
29 |
28 |
27 |
26 8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
N |
Z |
C |
V |
Q |
DNM(RAZ) |
I |
F |
T |
M |
M |
M |
M |
M |
条件码标志:N,Z,C,V 大多数指令可以测试这些条件码标志以决定程序指令如何执行
控制位:最低8 位I,F,T 和M 位用做控制位。当异常出现时改变控制位。当处理器在特权模式下也可以由软件改变。
中断禁止位:I 置1 则禁止IRQ 中断。F 置1 则禁止FIQ 中断。T 位:T=0 指示ARM 执行。T=1 指示Thumb 执行。在这些架构系统中,可自由地使用能在ARM 和Thumb 状态之间切换的指令。
模式位:M0, M1, M2, M3 和M4 (M[4:0]) 是模式位.这些位
决定处理器的工作模式.如表2-1 所示。
表4-1 ARM 工作模式M[4:0]
|
M[4:0] |
模式 |
可存取的寄存器 |
|
0b10000 |
用户模式 |
PC, R14~R0,CPSR |
|
0b10001 |
FIQ模式 |
PC, R14_fiq~R8_fiq,R7~R0,CPSR,SPSR_fiq |
|
0b10010 |
IRQ模式 |
PC, R14_irq~R8_fiq,R12~R0,CPSR,SPSR_irq |
|
0b10011 |
管理模式 |
PC, R14_svc~R8_svc,R12~R0,CPSR,SPSR_svc |
|
0b10111 |
中止 |
PC, R14_abt~R8_abt,R12~R0,CPSR,SPSR_abt |
|
0b11011 |
未定义 |
PC, R14_und~R8_und,R12~R0,CPSR,SPSR_und |
|
0b11111 |
系统 |
PC, R14~R0,CPSR |
其它位程序状态寄存器的其它位保留,用作以后的扩充。
4.1.3. 实验操作步骤
1. 执行ADS1.2开发环境,打开实验系统例程目录下ARMcode_test 子目录下的ARMcode.mcp 工程文件。
2. 透过操作菜单栏或使用快捷命令编译链接项目。
3. 选择Debug 菜单Remote Connect 进行连接软件仿真器,执行Download命令下载程序,并打开寄存器窗口。
4. 单步执行程序并观察和记录寄存器R0-R15 的值变化。
5. 结合实验内容和相关数据,观察程序执行,透过实验加深理解ARM指令的使用。
4.1.4 试验程序代码
;本程序将数据区从数据区SRC复制到目标数据区DST。复制时,以8个字节为单位进行。对于
;最后所剩不足的8个字节的数据,以字为单位进行复制,这时程序跳转到copywords处执行。
;在进行以8个字为单位的数据复制时,保存了所有的8个工作寄存器。
;设置本段程序的名称(Block)及属性
AREA Block,CODE,READONLY
;设置将要复制的字数(定义变量num,并赋值为20)
num EQU 20
;程序入口标志
ENTRY
start
;r0寄存器指向源数据区(SRC 标识的地址放入R0)
LDR r0,=src
;r1寄存器指向目标数据区(DST 标识的地址放入R1)
LDR r1,=dst
;r2指定将要复制的字数(装载num 的值到R2)
MOV r2, #num
;设置数据栈指针(R13),用于保存工作寄存器数值(设定SP堆栈开始地址为0x400)
MOV sp, #0x400
;进行以8个字节为单位的数据复制
blockcopy
;需要进行的以8个字为单位的复制次数( R2 右移3 位后的值放入R3)
MOVS r3,r2, LSR #3
;对于剩下的不足8个字的数据,跳转到copywords,以字为单位复制(判断是否为0,为0 跳移)
BEQ copywords
;保存工作寄存器(把R4 到R11 的值保存到SP 标识的堆栈中)
STMFD sp!, {r4-r11}
octcopy
;从数据区读取8个字节的数据,放到8个寄存器中,并更新目标数据区指针r0(把R0 中的地址标识的内容顺序装载到R4 到R11 中)
LDMIA r0!, {r4-r11}
;将这8个字数据写入到目标数据区,并更新目标数据区指针r1(把R4 到R11 的值顺序保存到以R1 起始地址的内存中)
STMIA r1!, {r4-r11}
;将块的复制次数减1 (R3 -1 计数)
SUBS r3, r3, #1
;循环,直到完成以8个字为单位的块复制
BNE octcopy
;需要注意的是,LDMIA 或者STMIA 指令执行后,R0,R1 的值产生变化,每一次寄存器操作,R0 或者R1 的值会自动增加一个字节的量,这里操作了8 个寄存器,R0 或者R1 的值也相应增加了8 个字节
;恢复工作寄存器值(把刚才保存的SP 堆栈中的值恢复到R4 到R11 中)
LDMFD sp!, {r4-r11}
copywords
;剩下不足8个字的数据的字数(逻辑与,把R2 前7 位扔掉)
ANDS r2, r2, #7
;数据复制完成(判断是否为0,为0 跳移)
BEQ stop
wordcopy
;从源数据区读取18个字的数据,放到r3寄存器中,并更新目标数据区指针r0(把R0 表示地址的内容的后4 位全部拷贝到R3)
LDR r3, [r0], #4
;将这r3中数据写入到目标数据区中,并更新目标数据区指针r1 (把R3 的内容,放入以R1 为起始地址的4 位内存中)
STR r3, [r1], #4
;将字数减1;(R2 -1 放回R2)
SUBS r2, r2, #1
;循环,直到完成以字为单位的数据复制(判断是否为0,不为0 跳移,同样的,这里R0,R1 操作后,R0,R1 会自动加上便宜量)
BNE wordcopy
stop
;从应用程序中退出
MOV r0, #0x18
LDR r1, =0x20026
SWI 0x123456
;定义数据区bloackdata
AREA Bloackdata, DATA, READWRITE
;定义源数据区src及目标数据区dst
src DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4
dst DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
;结束汇编
END
4.1.5 实验练习题
1. 撰写程序循环对R4~R11 进行8 次累加,R4~R11 起始值为1∼8,每次加操作后把R4~R11 的内容放入SP 堆栈中,SP 初始设定为0x800。最后把R4~R11 用LDMFD 指令清空值为0。
2. 对于每一种ARM 的寻址方法,简短的写出相对的应用程序片段。
4.2 ARM 处理器工作模式实验
4.2.1. 实验说明
实验目的:透过实验掌握ARM 处理器工作模式的切换。
实验设备:软件需要ADS1.2开发环境,Windows 98/2000/NT/XP。
实验内容:透过ARM 组译指令,在各种处理器模式下切换并观察各种模式下缓存器的区别;掌握ARM 不同模式的进入与退出。
4.2.2. 实验原理
ARM 处理器模式
ARM 架构支持下表2-2 所列的7 种处理器模式。
|
工作模式 |
描述 |
|
用户模式(User,usr) |
正常程序执行的模式 |
|
快速中断模式(FIQ,fig) |
用于高速数据传输和数据处理 |
|
外部中断模式(IRQ,irq) |
用于通常的中断处理 |
|
特权模式(管理模式)(Supervisor,sve) |
共操作系统使用的一种模式 |
|
数据访问中止模式(Abort,abt) |
用于虚拟存储及存储保护 |
|
未定义指令中断模式(Undefind,und) |
用于支持通过软件方针的协处理器 |
|
系统模式(System,sys) |
用于运行特权的操作系统任务 |
大多数应用程序在用户模式下执行。当处理器工作在用户模式时,正在执行的程序不能存取某些被保护的系统资源,也不能改变模式,除非例外(exception)发生。这允许适当撰写操作系统来控制系统资源的使用。
除用户模式外的其它模式称未特权模式。它们可以自由的存取系统资源和改变模式。其中的5 种称为异常模式,即
n FIQ(Fash Interrupt request);
n IRQ(Interrupt ReQuest);
n 管理(Supervisor);
n 中止(Abort) ;
n 未定义(Underfined) 。
当特定的异常出现时,进入相应的模式。每种模式都有某些附加的寄存器,以避免异常出现时用户模式的状态不可靠。
剩下的模式是系统模式。仅ARM 架构V4 以及以上的版本有该模式。不能由于任何异常而进入该模式。它与用户模式有完全相同的寄存器。然而它是特权模式,不受用户模式的限制。它供需要存取系统资源的操作系统工作使用,单希望避免使用与例外模式有关的附加寄存器。避免使用附加寄存器保证了当任何异常出现时,都不会使工作的状态不可靠。
4.2.3. 实验操作步骤
1.开发环境,打开实验系统例程目录下ARMMode_test\ARMMode.MCP 项目,并编译链接项目。
3. 单步执行程序并观察和记录CPSP 和SPSR 缓存器值的变化;并观察在相应模式下执行程序后对应缓存器值的变化。
4. 结合实验内容和相关数据,观察程序执行,透过实验加深理解和掌握
4.2.4 试验程序代码
;设置本段程序的名称(Block)及属性
AREA Block,CODE,READONLY
;程序入口标志
ENTRY
start
B Reset_Handler
Undefined_Handler
B Undefined_Handler
B SWI_Handler
Prefetch_Handler
B Prefetch_Handler
Abort_Handler
B Abort_Handler
NOP ;空操作
IRQ_Handler
B IRQ_Handler
FIQ_Handler
B FIQ_Handler
SWI_Handler
mov pc, lr
;前面部分是处理程序,主要处理各种模式的入端口跳移
Reset_Handler
;into System mode
MRS R0,CPSR ;复制CPSR 到R0
BIC R0,R0,#0x1F ;清除R0 的后5 位
ORR R0,R0,#0x1F ;设定R0 的最后5 位为11111
MSR CPSR_c,R0 ;把R0 装载到CPSR,切换到系统模式
MOV R0, #1 ;对系统模式下的R0 赋值,下面的R1~R15 一样
MOV R1, #2
MOV R2, #3
MOV R3, #4
MOV R4, #5
MOV R5, #6
MOV R6, #7
MOV R7, #8
MOV R8, #9
MOV R9, #10
MOV R10, #11
MOV R11, #12
MOV R12, #13
MOV R13, #14
MOV R14, #15
;into FIQ mode
MRS R0,CPSR
BIC R0,R0,#0x1F
ORR R0,R0,#0x11 ;设定R0 的最后5 位为10001
MSR CPSR_c,R0 ;把R0 装载到CPSR,切换到Fiq 模式
MOV R8, #16 ;给Fiq 模式的特有缓存器R8 赋值, 下面的R9~R14 一样
MOV R9, #17
MOV R10, #18
MOV R11, #19
MOV R12, #20
MOV R13, #21
MOV R14, #22
;into SVC mode
MRS R0,CPSR
BIC R0,R0,#0x1F
ORR R0,R0,#0x13 ;设定R0 的最后5 位为10011
MSR CPSR_c,R0 ;把R0 装载到CPSR,切换到Svc 模式
MOV R13, #23 ;给SVC 模式的特有缓存器R13 赋值, 下面的R14 一样
MOV R14, #24
;into Abort mode
MRS R0,CPSR
BIC R0,R0,#0x1F
ORR R0,R0,#0x17 ;设定R0 的最后5 位为10111
MSR CPSR_c,R0 ;把R0 装载到CPSR,切换到Abort 模式
MOV R13, #25 ;给Abort 模式的特有缓存器R13 赋值, 下面的R14 一样
MOV R14, #26
;into IRQ mode
MRS R0,CPSR
BIC R0,R0,#0x1F
ORR R0,R0,#0x12 ;设定R0 的最后5 位为10010
MSR CPSR_c,R0 ;把R0 装载到CPSR,切换到IRQ 模式
MOV R13, #27 ;给IRQ 模式的特有缓存器R13 赋值, 下面的R14一样
MOV R14, #28
;into UNDEF mode
MRS R0,CPSR
BIC R0,R0,#0x1F
ORR R0,R0,#0x1b ;设定R0 的最后5 位为11011
MSR CPSR_c,R0 ;把R0 装载到CPSR,切换到UNDEF 模式
MOV R13, #29 ;给UNDEF 模式的特有缓存器R13 赋值, 下面的R14 一样
MOV R14, #30
B Reset_Handler ;跳移到最开始地方循环
END
4.2.5. 实验练习题
1. 参考例子,把其中系统模式程序更改为使用者模式程序,编译除错,观察执行结果,检查是否正确,如果有有错误分析其原因。(提示:不能从使用者模式直接切换到其它模式,可以先使用SWI 指令切换到管理模式)。
|