主题 : 栈指针问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 2937
精华: 0
发帖: 35
金钱: 330 两
威望: 299 点
综合积分: 70 分
注册时间: 2008-12-17
最后登录: 2013-01-30
楼主  发表于: 2009-04-12 19:39

 栈指针问题

Reset:                 
    ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈
    bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启
   
    bl  clock_init          @ 设置MPLL,改变FCLK、HCLK、PCLK
   
    bl  memsetup            @ 设置存储控制器以使用SDRAM
    bl  copy_steppingstone_to_sdram     @ 复制代码到SDRAM中
    ldr pc, =on_sdram                   @ 跳到SDRAM中继续执行
   
on_sdram:
    msr cpsr_c, #0xd2       @ 进入中断模式
    ldr sp, =4096           @ 设置中断模式栈指针
    msr cpsr_c, #0xdf       @ 进入系统模式
    ldr sp, =0x34000000     @ 设置系统模式栈指针,
    bl  init_led            @ 初始化LED的GPIO管脚
    bl  timer0_init         @ 初始化定时器0  
    bl  init_irq            @ 调用中断初始化函数,在init.c中
    msr cpsr_c, #0x5f       @ 设置I-bit=0,开IRQ中断
   
    ldr lr, =halt_loop      @ 设置返回地址
    ldr pc, =main           @ 调用main函数
如上程序中, ldr sp, =4096           @ 设置栈指针,  ldr sp, =4096           @ 设置中断模式栈指针  , ldr sp, =0x34000000     @ 设置系统模式栈指针,这几个值是如何确定的啊,对汇编头疼死了,望高手给指点下
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2009-04-12 23:40
在Reset中的
ldr sp, =4096
是把当前模式的堆栈指针设置为4096 (0x1000), 因为此时,代码在SRAM中运行,地址空间为0 - 4K, 因此可以把栈指针设定到地址空间最顶层

在on_sdram中的
    msr cpsr_c, #0xd2       @ 进入中断模式
    ldr sp, =4096           @ 设置中断模式栈指针
    msr cpsr_c, #0xdf       @ 进入系统模式
    ldr sp, =0x34000000     @ 设置系统模式栈指针,
这是分别设定中断模式和系统模式下的堆栈指针到4096 (SRAM顶层)和0x34000000(SDRAM的64M顶层,此时SDRAM已经初始化,可以使用了)。
ARM在各种执行模式下都需要设置各自的堆栈指针,这就是为什么你看到那么多次ldr sp的操作了。另外,由于堆栈向下生长,这是为什么可以将堆栈指针设定到地址空间顶层的原因。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 2937
精华: 0
发帖: 35
金钱: 330 两
威望: 299 点
综合积分: 70 分
注册时间: 2008-12-17
最后登录: 2013-01-30
2楼  发表于: 2009-04-13 09:18
哦,晓得了,谢谢版主的指教,受益匪浅。