打印
[ZLG-ARM]

关于堆栈初始化程序中的疑问!!急求,希望有详细解答!

[复制链接]
2023|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zlg_arm|  楼主 | 2007-5-3 10:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
; 名称:InitStack
; 功能:堆栈初始化,即初始化各模式下的堆栈指针。
; 入口参数:无
; 出口参数:无
; 说明:在特权模式下调用此子程序,比如复位后的管理模式
InitStack    
            MOV     R0, LR        ; R0 <= LR,因为各种模式下R0是相同的

;设置管理模式堆栈
            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_LEGTH - 1)*4
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
UsrStackSpace         SPACE      USR_STACK_LEGTH * 4     ; 用户(系统)模式堆栈空间
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      ; 未定义模式堆栈    


上面是一段堆栈初始化程序!!我一直没有弄明白这个dcd指令和space指令有什么区别?书上写不都是用于申明一段空间吗?!
为什么用了space取得了空间,并且前面的空间名称也有了不直接使用,还要用dcd再指名一次???

急求,初学者!

相关帖子

沙发
computer00| | 2007-5-3 10:18 | 只看该作者

DCD只分配一个字来保存堆栈栈底地址,而space才是真正的分配

使用特权

评论回复
板凳
zlg_arm|  楼主 | 2007-5-3 10:32 | 只看该作者

谢谢

谢谢,看来我还要好好的研究研究这方面的东西!!!

使用特权

评论回复
地板
zlgARM| | 2007-5-4 11:32 | 只看该作者

zlg_arm

DCD定一个字,用以保存堆栈的栈顶地址。这里定义的堆栈是向下生长的。

搜索一下宛城布衣的一篇《ARM常用指令集》,里面有很详细地讲汇编指令和伪指令。

使用特权

评论回复
5
zlg_arm|  楼主 | 2007-5-4 21:06 | 只看该作者

继续一个问题

如下代码,如果我不使用space来分配,甚至可以不使用dcd指令,我就直接给那些各种模式下的sp的指针附值,只要自己在程序中控制好,保证不让代码段的指令会到这段地址,是不是就可以了?那些space和dcd,主要是为了程序的


;;;定义堆栈的大小
;;;USR_STACK_LEGTH     EQU         10
;;;SVC_STACK_LEGTH     EQU         10
;;;FIQ_STACK_LEGTH     EQU         10
;;;IRQ_STACK_LEGTH     EQU         10
;;;ABT_STACK_LEGTH     EQU         10
;;;UND_STACK_LEGTH     EQU         10

            AREA    Example7,CODE,READONLY    ; 声明代码段Example7
            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    ; 初始化各模式下的堆栈指针
            
            ; 打开IRQ中断 (将CPSR寄存器的I位清零)
            MRS        R0,CPSR            ; R0 <= CPSR
            BIC        R0,R0,#0x80 
            MSR        CPSR_cxsf,R0    ; CPSR <= R0
                        
            ; 切换到用户模式
            MSR     CPSR_c, #0xd0
            MRS        R0,CPSR
            
            ; 切换到管理模式
            MSR     CPSR_c, #0xdf
            MRS        R0,CPSR        

HALT        B        HALT
            
; 名称:InitStack
; 功能:堆栈初始化,即初始化各模式下的堆栈指针。
; 入口参数:无
; 出口参数:无
; 说明:在特权模式下调用此子程序,比如复位后的管理模式
InitStack    
            MOV     R0, LR        ; R0 <= LR,因为各种模式下R0是相同的

;设置管理模式堆栈
            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     0x40003040
StackSvc    DCD     0x4000ff50
StackIrq    DCD     0x4000ff60
StackFiq    DCD     0x4000ff70
StackAbt    DCD     0x4000ff80
StackUnd    DCD     0x4000ff90

;;; 分配堆栈空间 
;;;            AREA    MyStacks, DATA, NOINIT, ALIGN=2
;;;UsrStackSpace         SPACE      USR_STACK_LEGTH * 4     ; 用户(系统)模式堆栈空间
;;;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      ; 未定义模式堆栈    


使用特权

评论回复
6
zlg_arm|  楼主 | 2007-5-4 21:08 | 只看该作者

接上面的,没有打完

如上代码,如果我不使用space来分配,甚至可以不使用dcd指令,我就直接给那些各种模式下的sp的指针附值,只要自己在程序中控制好,保证不让代码段的指令会到这段地址,是不是就可以了?


可不可以理解为
space,主要是为了程序的初始化为0值
dcd主要的作用是为了使得程序的可读性增强

使用特权

评论回复
7
computer00| | 2007-5-4 21:57 | 只看该作者

自己保证多辛苦? 让编译器帮你分配不是更好?

就像C语言中的变量一样,你不用理会它的物理地址是多少.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

72

帖子

0

粉丝