共2条
1/1 1 跳转至页
问
被网友问到了,没想明白,请教大家
在启动代码中有:
;定义堆栈的大小
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: 对,就是这么理解的!
在启动代码中有:
;定义堆栈的大小
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 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 | |
【FRDM-MCXN947评测】核间通信MUTEX被打赏50分 |