堆栈2

今天在搞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

  AREA Example5,CODE,READONLY
  ENTRY
  CODE32
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

      ;打开IRQ中断(cpsr寄存器的I位零位)
      MRS R0,CPSR
      BIC R0,R0,#0X80
      MSR CPSR_cxsf,R0

      ;切换到用户模式
      MSR CPSR_c,#0XD0
      MRS R0,CPSR

      ;切换到管理模式
      MSR CPSR_c,#0XDF
      MRS R0,CPSR

HALT B HALT
InitStack
      MOV R0,LR
      ;设置管理模式堆栈
      MSR CPSR_c,#0xd3
      LDR SP,StackSvc
      ;设置中断模式堆栈
      MSR CPSR_c,#0xd2
      LDR SP,STackIrq
      ;设置快速中断模式堆栈
      MSR CPSR_c,#0XD1
      LDR SP,STackFiq
      ;设置中止模式堆栈
      MSR CPSR_c,#0XD7
      LDR SP,STackAbt
      ;设置未定义模式堆栈
      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

;分配堆栈空间
  AREA MyStacks,DATA,NOINIT,ALIGN=2
UsrStackSpace SPACE 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

 再贴上两幅图

 

注意上面红色圈住的部分。上面的图说明以下以点:

1.程序在0x0000808C处结束

2.程序后面的伪代码诸如:

StackUsr DCD UsrStackSpace+(USR_STACK_LENGTH-1)*4
StackSvc DCD SvcStackSpace+(SVC_STACK_LENGTH-1)*4

它们的地址是紧跟着程序末尾的

3.LDR SP,StackSvc是将StackSvc这个标号处的内容给sp,如图StackSvc标号的地址为0x8094但是其内容是

由下面的语句决定:

StackSvc DCD SvcStackSpace+(SVC_STACK_LENGTH-1)*4决定

SvcStackSpace标号的地址为0x81a8,所以StackSvc的内容为0x81a4

由上面三点认识,可以得出如下结论:各个模式下的堆栈指针不是一个固定的值。而是由程序

编译后根据程序大小来决定的。我们可以规定堆栈的大小,初如化的时候只需要将堆栈指针

放到合适的位置即可。在正式的程序运行时,可能我们所用的栈可能比规定的堆栈大,那么堆栈指针

可能越界,就会造成不可预知的后果。这个结论也支持了前面的“堆栈”那篇文章的推理。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值