在main()之前,IAR都做了啥.docVIP

  • 5
  • 0
  • 约8.01千字
  • 约 10页
  • 2018-01-02 发布于河南
  • 举报
在main()之前,IAR都做了啥

在main()之前,IAR都做了啥 [原创]在main()之前,IAR都做了啥? 收藏 最近要在Cortex-M3上写一个简单的操作系统,打算使用IAR,为了写好启动代码,花了一些时间了解了IAR在main()以前做了些什么事。 首先系统复位时,Cortex-M3从代码区偏移0获取栈顶地址,用来初始化MSP寄存器的值。 接下来从代码区偏移0取第一个指令的跳转地址。这些地址,是CM3要求放置中断向量表的地方。 这里是一个程序的启动区的反汇编: __vector_table: 2600 2000 7E1D 0800 这个程序是由IAP程序来启动的,IAP程序获取0的MSP值(0,并设置为MSP的值,即主堆栈最大范围是00x200025FF。接下来IAP程序获取0的Reset_Handler的地址 (0x08007E1D),并跳转到Reset_Handler()执行。 IAP在这里完全是模仿了Cortex-M3的复位序列,也就是说,在没有IAP的系统上,CM3只能从0取MSP,从 0取第一条指令所处地址。而IAP就存在在0个地址上,IAP的启动,已经消耗掉了这个复位序列,所以 IAP要启动UserApp程序的时候,也是完全模仿Cortex-M3的复位序列的。 接下来我们看看复位后第一句指令——Reset_Handler()函数里有什么。 若我们使用的是ST公司标准外设库,那么已经有了现成的Reset_Handler,不过他是弱定义——PUBWEAK,可以被我们重写的同名函数覆盖。一般来说,我们使用的都是ST提供的Reset_Handler,在V3.4版本的库中,可以在startup_stm32f10x_xx.s中找到这个函数: PUBWEAK Reset_Handler SECTION .text:CODE:REORDER(2) Reset_Handler LDR R0, =SystemInit BLX R0 LDR R0, =__iar_program_start BX R0 看来ST没有做太多的事,他只调用了自家库提供的SystemInit函数进行系统时钟、Flash读取的初始化,并把大权交给了 __iar_program_start这个IAR提供的“内部函数”了,我们就跟紧这个__iar_program_start跳转,看看IAR做了什么,上面一段代码的反汇编如下: Reset_Handler: __iar_section$$root: 08007E1C 4801 LDR R0, [PC, #0x4]; LDR R0, =SystemInit 08007E1E 4780 BLX R0;BLX R0 08007E20 4801 LDR R0, [PC, #0x4];LDR R0, =__iar_program_start 08007E22 4700 BX R0;BX R0 08007E24 6C69 08007E26 0800 08007E28 7D8D 08007E2A 0800 细心的观众会发现地址是0x08007E1C,比我们查到的0x08007E1D差了1,这是ARM家族的遗留问题,因为ARM处理器的指令至少是半字对齐的(16位THUMB指令集 or 32位ARM指令集),所以PC指针的LSB是常为0的,为了充分利用寄存器,ARM公司给PC的LSB了一个重要的使命,那就是在执行分支跳转时,PC 的LSB=1,表示使用THUMB模式,LSB=0,表示使用ARM模式,但在最新的Cortex-M3内核上,只使用了THUMB-2指令集挑大梁,所以这一位要常保持1,所以我们查到的地址是0x08007E1D(C=1100,D=1101),放心,我们的CM3内核会忽略掉LSB(除非为0,那么会引起一个fault),从而正确跳转到0x08007E1C。 从0x08007E20处的加载指令,我们可以算出__iar_program_start所处

文档评论(0)

1亿VIP精品文档

相关文档