;ARM处理器不同模式的切换的汇编示例
分类: LINUX
;ARM处理器不同模式的切换的汇编示例
;定义堆栈大小
USR_STACK_LENGTH EQU 64 ;用户模式
SVC_STACK_LENGTH EQU 0 ;管理模式
FIQ_STACK_LENGTH EQU 16 ;快速中断模式
IRQ_STACK_LENGTH EQU 64 ;中断模式
ABT_STACK_LENGTH EQU 0 ;中止模式
UND_STACK_LENGTH EQU 0 ;未定义模式
;定义堆栈大小
USR_STACK_LENGTH EQU 64 ;用户模式
SVC_STACK_LENGTH EQU 0 ;管理模式
FIQ_STACK_LENGTH EQU 16 ;快速中断模式
IRQ_STACK_LENGTH EQU 64 ;中断模式
ABT_STACK_LENGTH EQU 0 ;中止模式
UND_STACK_LENGTH EQU 0 ;未定义模式
AREA Example3,CODE,READONLY ; 声明只读代码段Example3
ENTRY ;标识程序入口点
CODE32 ;声明32位ARM指令
START MOV R0,#0
MOV R1,#1
MOV R2,#2
MOV R3,#3
MOV R4,#4
MOV R5,#5
MOV R6,#6
MOV R7,#7
MOV R8,#8
MOV R9,#9
MOV R10,#10
MOV R11,#11
MOV R12,#12
BL InitStack ;初始化各模式下的堆栈指针BL(Branch with Link跳转将PC拷入LR,用于子程序返回)
;打开IRQ中断(即将CPSR[7]清零)读取-修改-写回
MRS R0,CPSR ;R0<-CPSR
BIC R0,R0,#0X80
MSR CPSR_cxsf,R0 ;CPSR<-R0
;切换到用户模式(CPSR[4:0]=10000,同时CPSR[7:6]=11,CPSR[5]=0保留,即CPSR[7:0]
ENTRY ;标识程序入口点
CODE32 ;声明32位ARM指令
START MOV R0,#0
MOV R1,#1
MOV R2,#2
MOV R3,#3
MOV R4,#4
MOV R5,#5
MOV R6,#6
MOV R7,#7
MOV R8,#8
MOV R9,#9
MOV R10,#10
MOV R11,#11
MOV R12,#12
BL InitStack ;初始化各模式下的堆栈指针BL(Branch with Link跳转将PC拷入LR,用于子程序返回)
;打开IRQ中断(即将CPSR[7]清零)读取-修改-写回
MRS R0,CPSR ;R0<-CPSR
BIC R0,R0,#0X80
MSR CPSR_cxsf,R0 ;CPSR<-R0
;切换到用户模式(CPSR[4:0]=10000,同时CPSR[7:6]=11,CPSR[5]=0保留,即CPSR[7:0]
=11010000=0xd0)
MSR CPSR_c,#0xd0
;保存一下当前CPSR,将CPSR传入R0
MRS R0,CPSR
;切换到管理模式(CPSR[4:0]=10011,同时CPSR[7:6]=11,CPSR[5]=0保留,即CPSR[7:0]
MSR CPSR_c,#0xd0
;保存一下当前CPSR,将CPSR传入R0
MRS R0,CPSR
;切换到管理模式(CPSR[4:0]=10011,同时CPSR[7:6]=11,CPSR[5]=0保留,即CPSR[7:0]
=11010011=0xd3)
MSR CPSR_c,#0xd3
;保存一下当前CPSR,将CPSR传入R0
MRS R0,CPSR
HALT B HALT ;留在此处
MSR CPSR_c,#0xd3
;保存一下当前CPSR,将CPSR传入R0
MRS R0,CPSR
HALT B HALT ;留在此处
;初始化各模式下的堆栈子程序
;入口参数:无
;出口参数: 无
InitStack
MOV R0,LR ;R0<-LR,各模式下的R0是相同的
;设置管理模式下的堆栈,先切换到管理模式下再设置该模式下的SP MSR CPSR_c,#0xd3
LDR SP,StackSvc ;将StackSvc代表的地址装入SP
;设置中断模式下的堆栈,先切换到中断模式下再设置该模式下的SP
;中断模式CPSR[7:0]=110,10010
MSR CPSR_c,#0xd2
LDR SP,StackIrq
;设置中止模式下的堆栈,先切换到中断模式下再设置SP
MSR CPSR_c,#0xd7
LDR SP,StackAbt
;入口参数:无
;出口参数: 无
InitStack
MOV R0,LR ;R0<-LR,各模式下的R0是相同的
;设置管理模式下的堆栈,先切换到管理模式下再设置该模式下的SP MSR CPSR_c,#0xd3
LDR SP,StackSvc ;将StackSvc代表的地址装入SP
;设置中断模式下的堆栈,先切换到中断模式下再设置该模式下的SP
;中断模式CPSR[7:0]=110,10010
MSR CPSR_c,#0xd2
LDR SP,StackIrq
;设置中止模式下的堆栈,先切换到中断模式下再设置SP
MSR CPSR_c,#0xd7
LDR SP,StackAbt
;设置未定义模式下的堆栈
MSR CPSR_c,#0xdb
LDR SP,StackUnd
MSR CPSR_c,#0xdb
LDR SP,StackUnd
;设置系统模式下的堆栈
MSR CPSR_c,#0xdf
LDR SP,StackUsr
;返回
MOV PC,R0
;定义堆栈首地址,即最高地址处
StackUsr DCD UsrStackSpace+(USR_STACK_LENGTH-1)*4
StackSvc DCD SvcStackSpace+(SVC_STACK_LENGTH-1)*4
StackIrq DCD IrqStackSpace+(IRQ_STACK_LENGTH-1)*4
StackFiq DCD FiqStackSpace+(FIQ_STACK_LENGTH-1)*4
StackAbt DCD AbtStackSpace+(ABT_STACK_LENGTH-1)*4
StackUnd DCD UndStackSpace+(UND_STACK_LENGTH-1)*4
MSR CPSR_c,#0xdf
LDR SP,StackUsr
;返回
MOV PC,R0
;定义堆栈首地址,即最高地址处
StackUsr DCD UsrStackSpace+(USR_STACK_LENGTH-1)*4
StackSvc DCD SvcStackSpace+(SVC_STACK_LENGTH-1)*4
StackIrq DCD IrqStackSpace+(IRQ_STACK_LENGTH-1)*4
StackFiq DCD FiqStackSpace+(FIQ_STACK_LENGTH-1)*4
StackAbt DCD AbtStackSpace+(ABT_STACK_LENGTH-1)*4
StackUnd DCD UndStackSpace+(UND_STACK_LENGTH-1)*4
;分配栈堆空间
AREA MyStacks,DATA,NOINIT,ALIGN=2
UsrStackSpace SPACE USR_STACK_LENGTH*4 ;分配USR_STACK_LENGTH*4个字节
SvcStackSpace SPACE SVC_STACK_LENGTH*4
IrqStackSpace SPACE IRQ_STACK_LENGTH*4
FiqStackSpace SPACE FIQ_STACK_LENGTH*4
AbtStackSpace SPACE ABT_STACK_LENGTH*4
UndStackSpace SPACE UND_STACK_LENGTH*4
AREA MyStacks,DATA,NOINIT,ALIGN=2
UsrStackSpace SPACE USR_STACK_LENGTH*4 ;分配USR_STACK_LENGTH*4个字节
SvcStackSpace SPACE SVC_STACK_LENGTH*4
IrqStackSpace SPACE IRQ_STACK_LENGTH*4
FiqStackSpace SPACE FIQ_STACK_LENGTH*4
AbtStackSpace SPACE ABT_STACK_LENGTH*4
UndStackSpace SPACE UND_STACK_LENGTH*4
END
编译方法:
Edit->DebugRel Setting...
Target/Target Settings->Post-linker:ARM fromELF
ARM fromELF->Output format:Intel 32 bit Hex ,Output file name:输入文件名.hex
Project->Make
Project->Debug,启动AXD
选择单步执行Execute->Step(F10),查看Registers中显示的Current寄存器值,查看Variables中显示的变量值
Edit->DebugRel Setting...
Target/Target Settings->Post-linker:ARM fromELF
ARM fromELF->Output format:Intel 32 bit Hex ,Output file name:输入文件名.hex
Project->Make
Project->Debug,启动AXD
选择单步执行Execute->Step(F10),查看Registers中显示的Current寄存器值,查看Variables中显示的变量值
阅读(1407) | 评论(0) | 转发(0) |