USR_STACK_LEGTH EQU 64 SVC_STACK_LEGTH EQU 0 FIQ_STACK_LEGTH EQU 16 IRQ_STACK_LEGTH EQU 64 ABT_STACK_LEGTH EQU 0 UND_STACK_LEGTH EQU 0
AREA Example5, CODE, READONLY ENTRY CODE32 START MOV R0, #0 ;0x40000000 MOV R1, #1 ;0x40000004 MOV R2, #2 ;0x40000008 MOV R3, #3 ;0x4000000c MOV R4, #4 ;0x40000010 MOV R5, #5 ;0x40000014 MOV R6, #6 ;0x40000018 MOV R7, #7 ;0x4000001c MOV R8, #8 ;0x40000020 MOV R9, #9 ;0x40000024 MOV R10, #10 ;0x40000028 MOV R11, #11 ;0x4000002c MOV R12, #12 ;0x40000030 BL InitStack ;0x40000034 ;打开IRQ中断(将CPSR寄存器的I位清零) MRS R0,CPSR ;0x40000038 BIC R0,R0,#0X80 ;0x4000003c MSR CPSR_cxsf, R0 ;0x40000040 ;切换到用户模式 MSR CPSR_c, #0xd0 ;0x40000044 MRS R0, CPSR ;0x40000048 ;切换到管理模式 MSR CPSR_c, #0xdf ;0x4000004c MRS R0, CPSR ;0x40000050
HALT B HALT ;0x40000054
InitStack MOV R0, LR ;0x40000058 ;设置管理模式堆栈 MSR CPSR_c, #0xd3 ;0x4000005c LDR SP, StackSvc ;0x40000060 ;设置中断模式堆栈 MSR CPSR_c, #0xd2 ;0x40000064 LDR SP, StackIrq ;0x40000068 ;设置快速中断模式堆栈 MSR CPSR_c, #0xd1 ;0x4000006c LDR SP, StackFiq ;0x40000070 ;设置中止模式堆栈 MSR CPSR_c, #0xd7 ;0x40000074 LDR SP, StackAbt ;0x40000078 ;设置未定义模式堆栈 MSR CPSR_c, #0xdb ;0x4000007c LDR SP, StackUnd ;0x40000080 ;设置系统模式堆栈 MSR CPSR_c, #0xdf ;0x40000084 LDR SP,StackUsr ;0x40000088 MOV PC,R0 ;0x4000008c StackUsr DCD UsrStackSpace + (USR_STACK_LEGTH - 1)*4 ;0x40003000+FC(252)=0x400030FC(用户(系统)模式堆栈起始地址) StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)*4 ;0x40003100+(-4) =0x400030FC(管理模式堆栈起始地址) StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)*4 ;0x40003100+FC(252)=0x400031FC(向量中断模式堆栈起始地址) StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)*4 ;0x40003200+3C(60) =0x4000323C(快速中断模式起始地址) StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)*4 ;0x40003240+(-4) =0x4000323C(中止模式堆栈起始地址) StackUnd DCD UndStackSpace + (UND_STACK_LEGTH - 1)*4 ;0x40003240+(-4) =0x4000323C(未定义模式堆栈起始地址)
AREA MyStacks, DATA, NOINIT, ALIGN=2 UsrStackSpace SPACE USR_STACK_LEGTH * 4 ;0x40003000 连续分配256B SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;0x40003100 连续分配0B IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ;0x40003100 连续分配256B FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ;0x40003200 连续分配64B AbtStackSpace SPACE ABT_STACK_LEGTH * 4 ;0x40003040 连续分配0B UndStackSpace SPACE UND_STACK_LEGTH * 4 ;0x40003040 连续分配0B END
|
这段代码主要作用是为ARM各种工作模式分配堆栈。CPSR状态寄存器的值对应各个工作模式的情况如下:
31 30 29 28 --- 7 6 5 4 3 2 1 0
N Z C V I F T M4 M3 M2 M1 M0
0 1 0 0 0 0 User用户模式
0 1 0 0 0 1 FIQ 快中断模式
0 1 0 0 1 0 IRQ 中断模式
0 1 0 0 1 1 SVC 管理模式
0 1 0 1 1 1 ABT 中止模式
0 1 1 0 1 1 UND 未定义模式
0 1 1 1 1 1 SYS 系统模式
CPSR的N,Z,C,V是条件代码标志,含义如下:
(1)负标志N:运算结果的第31位值,记录标志设置操作的结果。
(2)零标志Z:如果标志设置运算结果为0,则置位。
(3)进位标志位C:记录无符号加法溢出,减法无借位,循环移位。
(4)溢出标志V:记录标志设置操作的有符号溢出。
I和F为中断标志位。T为处理器状态位。
当I置位时,IRQ中断禁止,否则IRQ使能
当F置位时,FIQ中断禁止,否则FIQ使能
当T置位时,处理器在Thumb状态。
当T清零时,处理器在ARM状态。
这里使用ADS1.2进行调试的,首先设置工程链接地址RO Base为0x40000000,RW Base为0x40003000,设置调试入口地址Image entry point为0x400000000。
这些值可以根据自己板子的情况设定。
使用AXD调试我们可以得到各个模式下的堆栈分配情况:
模式 起始地址 结束地址
SVC: 0x400030FC 0x400030FC
IRQ: 0x400031FC 0x40003100
FIQ: 0x4000323C 0x40003200
ABT: 0x4000323C 0x4000323C
UND: 0x4000323C 0x4000323C
SYS: 0x400030FC 0x40003000
阅读(2566) | 评论(0) | 转发(0) |