ARM9中LDR SP , = 4*1024 / LDR SP , = 0x34000000 的分析

本文详细解析了ARM处理器的启动过程,包括初始化栈指针、关闭看门狗、配置时钟等关键步骤,并介绍了不同模式下栈指针的设置原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

reset:                 
    ldr sp, = 4*1024           @ SP=4096,设置栈指针,后面会调用C函数,调用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, =4*1024           @ 设置中断模式栈指针
    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函数

 

如上程序中,由于ARM在各种执行模式下都需要设置各自的栈指针,所以"ldr sp,=xxxx"操作较多。根据ARM的ATPCS规则,对栈的操作属于FD(满递减),即栈指针一直指向栈顶元素,是按地址减小的方向增长的,所以一般将SP设置在地址的最高处。

 ldr sp, =4*1024,  ldr sp, =4*1024, ldr sp, =0x34000000 ,这几个值的确定与硬件关系很大:

1.在reset中:

    ldr sp, =4*1024:在ARM9(S3C2440)中,SRAM有效地址范围为0~4K,所以可以把栈初始指针设置在SRAM的有效地址的最高地址处,当然,如果空间够用,也可以设置小点儿,比如:ldr sp , = 2*1024 。

2.在on_sdram中:
    ldr sp, =4096           @ 设置中断模式栈指针
    ldr sp, =0x34000000     @ 设置系统模式栈指针,
这是分别设定中断模式和系统模式下的堆栈指针到4096(SRAM的有效地址的最高地址)和0x34000000(从0x30000000开始的64M的SDRAM的最高地址处,此时SDRAM已经初始化,可以使用了)。

我打开只发现这样一段: /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20009FFF; define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; define symbol __ICFEDIT_region_CCMRAM_end__ = 0x10001FFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; define symbol __ICFEDIT_size_heap__ = 0x200; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP };
最新发布
08-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值