这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 堆栈初始化疑问

共2条 1/1 1 跳转至

堆栈初始化疑问

院士
2006-09-17 18:14:16     打赏
堆栈初始化疑问



关键词: 堆栈     初始化     疑问    

院士
2006-12-22 22:43:00     打赏
2楼
问 被网友问到了,没想明白,请教大家

在启动代码中有:

;定义堆栈的大小
SVC_STACK_LEGTH         EQU         0
FIQ_STACK_LEGTH         EQU         0
IRQ_STACK_LEGTH         EQU         128
ABT_STACK_LEGTH         EQU         0
UND_STACK_LEGTH         EQU         0


Reset
        LDR     PC, ResetAddr
        LDR     PC, UndefinedAddr
        LDR     PC, SWI_Addr
        LDR     PC, PrefetchAddr
        LDR     PC, DataAbortAddr
        DCD     0xb9205f80
        LDR     PC, [PC, #-0xff0]
        LDR     PC, FIQ_Addr

ResetAddr           DCD     ResetInit
UndefinedAddr       DCD     Undefined
SWI_Addr            DCD     SoftwareInterrupt
PrefetchAddr        DCD     PrefetchAbort
DataAbortAddr       DCD     DataAbort
Nouse               DCD     0
IRQ_Addr            DCD     0
FIQ_Addr            DCD     FIQ_Handler


;未定义指令
Undefined
        B       Undefined

;软中断
SoftwareInterrupt
        B       SoftwareInterrupt

;取指令中止
PrefetchAbort
        B       PrefetchAbort

;取数据中止
DataAbort
        B       DataAbort

;快速中断
FIQ_Handler
        B       FIQ_Handler


StackSvc           DCD     SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq           DCD     FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt           DCD     AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackUnd           DCD     UndtStackSpace + (UND_STACK_LEGTH - 1)* 4


;/* 分配堆栈空间 */
        AREA    MyStacks, DATA, NOINIT, ALIGN=2
SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间
IrqStackSpace      SPACE   IRQ_STACK_LEGTH * 4  ;中断模式堆栈空间
FiqStackSpace      SPACE   FIQ_STACK_LEGTH * 4  ;快速中断模式堆栈空间
AbtStackSpace      SPACE   ABT_STACK_LEGTH * 4  ;中止义模式堆栈空间
UndtStackSpace     SPACE   UND_STACK_LEGTH * 4  ;未定义模式堆栈

其中,IRQ_STACK_LEGTH 为128,根据
IrqStackSpace      SPACE   IRQ_STACK_LEGTH * 4  ;中断模式堆栈空间
可知,IrqStackSpace 为128*4个字节空间的首地址,然后在
StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
中, IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4 = 128*4 + (128-1)*4 = (128+127)*4,就是说实际的irq堆栈大小为 (128+127)*4个字节,是这样的吗? 1: 是这样吗?StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4

中的IrqStackSpace 为128*4个连续字节的首地址,IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4 表示一个基址 加上一个内存大小的偏移量从而构成了128*4 个连续的字节空间? 2: 可如果是这样的话直接写为
StackIrq           DCD     (IRQ_STACK_LEGTH )* 4
不就可以了吗?为什么还要用到space语句呢? 3: 不是你讲的那样StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
这里的StackIrq是顶格写的,是一个标号,实质就是一个地址。这句伪指令,是将一个数值(IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4)放到一个地址上去(StackIrq)。

IrqStackSpace      SPACE   IRQ_STACK_LEGTH * 4
是从IrqStackSpace这个位置(地址)开始,分配一定长度(IRQ_STACK_LEGTH * 4)的空间。

StackIrq 实际上指向了堆栈的栈顶(这个堆栈的最高地址)。
请参考宛城布衣写的常用ARM指令集及汇编,里面有这两条指令的解释。 4: eyuge2说的对eyuge2说的很对,StakckIrq里放的是向量中断堆栈的栈顶地址 5: re我知道问题出在哪了,是我没有正确的理解DCD和SPACE的使用格式。

按照我楼顶的第一个帖子的理解是错误的,当时觉得那么理解也不妥当,因为那样的话就会有

(128+127)*4的字节作为堆栈空间了。

而在稍后发的第三个帖子里:


是这样吗?

StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4

中的IrqStackSpace 为128*4个连续字节的首地址,IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4 表示一个基址 加

上一个内存大小的偏移量从而构成了128*4 个连续的字节空间


的理解是正确的,但是混淆了DCD指令和SPACE指令的功能。

<label> DCD expr1 {,expr2}{,expr3}...

的意思是讲表达式的值存储在当前的地址中,此地址标号为label,只是将expr1,expr2,expr3...的值装在以label

开始的地址里,并不能分配expr1个连续的字节;

而SPACE的使用格式为

{label} SPACE  expr

这个指令才是真正的分配expr个连续的字节,而这些连续字节的首地址为label,

所以,


StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
中,IrStackSpace可以看作是一个基地址,(IRQ_STACK_LEGTH - 1)* 4作为一个偏移量,两者的和就是这个地址的最

高端,这个最高地址就是堆栈StackIrq的栈顶。而 IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4 的结果毕竟是一个

数值,将这个数值用 DCD 伪指令存放在标号为 StackIrq的内存地址中,这样当访问 StackIrq 时就读取了他的栈顶

的地址了。

刚才看了eyuge2 和 秋天的枫叶 的回帖觉得这么理解应该是对得了,谢谢两位,谢谢大家。 6: 对,就是这么理解的!

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]