STM32单片机启动文件startup_stm32f10x_hd.s详解

启动文件源码如下:

; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

;栈初始化
Stack_Size      EQU     0x00000400   						;EQU定义栈空间的大小 1024字节,栈空间由编译器自动分配变量所占内存,该汇编语句等效于#define Stack_Size 0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3 	;定义一个名为STACK的内存单元,它是可读写的,对齐方式为2^3=8字节对齐
Stack_Mem       SPACE   Stack_Size   						;SPACE分配连续的栈存储空间,大小为0x00000400(1K),把首地址赋给Stack_Mem
__initial_sp     											;初始化堆栈指针,指向堆栈顶。
                                                  
; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

;堆初始化
Heap_Size       EQU     0x00000200   						;EQU定义堆空间的大小,堆空间由人为手动分配变量所占内存,该汇编语句等效于#define Heap_Size 0x00000200

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3  	;定义一个名为HEAP的内存单元,它是可读写的,对齐方式为2^3=8字节对齐
__heap_base								 					;堆起始地址 
Heap_Mem        SPACE   Heap_Size							;SPACE分配连续的堆存储空间,大小为0x00000200(512Bytes),把首地址赋给Heap_Mem
__heap_limit							  					;堆终止地址,与__heap_base配合限制堆的大小 

                PRESERVE8					   				;告诉编译器以8字节对齐,命令指定当前文件保持栈的八字节对齐
                THUMB					  					;告诉编译器使用THUMB指令集,THUMB 必须位于使用新语法的任何Thumb代码之前;定义复位段(中断向量表),并初始化

;中断向量表定义
; Vector Table Mapped to Address 0 at Reset					;中断向量表默认从地址0开始,如果使用了向量表重定位,则从重定位地址开始。假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000。
                AREA    RESET, DATA, READONLY				;定义一个名为RESET的数据段,它是只读类型的。
                EXPORT  __Vectors							;声明全局变量_Vectors,该标号可在其他文件中使用,表示中断向量表入口地址
                EXPORT  __Vectors_End						;向量表终止地址
                EXPORT  __Vectors_Size						;向量表空间大小


__Vectors       DCD     __initial_sp               ; Top of Stack  Top of Stack 第一个表项是栈顶地址;该处物理地址值即为 __Vetors 标号所表示的值;该地址中存储__initial_sp所表示的地址值,
;大小为一个字(32bit) 
                DCD     Reset_Handler              ; Reset Handler     		复位异常,装载完栈顶后,第一个执行的,并且不返回。
                DCD     NMI_Handler                ; NMI Handler 			不可屏蔽中断
                DCD     HardFault_Handler          ; Hard Fault Handler  	硬件错误中断
                DCD     MemManage_Handler          ; MPU Fault Handler  	内存管理错误中断
                DCD     BusFault_Handler           ; Bus Fault Handler  	总线错误中断,一般发生在数据访问异常,比如fsmc访问不当
                DCD     UsageFault_Handler         ; Usage Fault Handler 	用法错误中断,一般是预取值,或者位置指令,数据处理等错误
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler  		系统调用异常,主要是为了调用操作系统内核服务
                DCD     DebugMon_Handler           ; Debug Monitor Handler  调试监视异常
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler  		挂起异常,此处可以用作RTOS的上下文切换异常,这是被推荐使用的,因为Cortex-M4会在异常发生时自动保存R0-R3,R12,R13(堆栈指针SP),R14(链接地址,也叫返回地址LR,在异常返回时使用),R15(程序计数器PC,为当前应用程序+4)和中断完成时自动恢复,我们只需保存R4-R11,大大减少了中断响应和上下文切换的时间。
                DCD     SysTick_Handler            ; SysTick Handler  		滴答定时器,为操作系统内核时钟

                ; External Interrupts              							外部中断
                DCD     WWDG_IRQHandler            ; Window Watchdog
                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler          ; Tamper
                DCD     RTC_IRQHandler             ; RTC
                DCD     FLASH_IRQHandler           ; Flash
                DCD     RCC_IRQHandler             ; RCC
                DCD     EXTI0_IRQHandler           ; EXTI Line 0
                DCD     EXTI1_IRQHandler           ; EXTI Line 1
                DCD     EXTI2_IRQHandler           ; EXTI Line 2
                DCD     EXTI3_IRQHandler           ; EXTI Line 3
                DCD     EXTI4_IRQHandler           ; EXTI Line 4
                DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
                DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
                DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
                DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
                DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
                DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
                DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
                DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2
                DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
                DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
                DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
                DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
                DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
                DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
                DCD     TIM1_UP_IRQHandler         ; TIM1 Update
                DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
                DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
                DCD     TIM2_IRQHandler            ; TIM2
                DCD     TIM3_IRQHandler            ; TIM3
                DCD     TIM4_IRQHandler            ; TIM4
                DCD     I2C1_EV_IRQHandler         ; I2C1 Event
                DCD     I2C1_ER_IRQHandler         ; I2C1 Error
                DCD     I2C2_EV_IRQHandler         ; I2C2 Event
                DCD     I2C2_ER_IRQHandler         ; I2C2 Error
                DCD     SPI1_IRQHandler            ; SPI1
                DCD     SPI2_IRQHandler            ; SPI2
                DCD     USART1_IRQHandler          ; USART1
                DCD     USART2_IRQHandler          ; USART2
                DCD     USART3_IRQHandler          ; USART3
                DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
                DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
                DCD     TIM8_BRK_IRQHandler        ; TIM8 Break
                DCD     TIM8_UP_IRQHandler         ; TIM8 Update
                DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation
                DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare
                DCD     ADC3_IRQHandler            ; ADC3
                DCD     FSMC_IRQHandler            ; FSMC
                DCD     SDIO_IRQHandler            ; SDIO
                DCD     TIM5_IRQHandler            ; TIM5
                DCD     SPI3_IRQHandler            ; SPI3
                DCD     UART4_IRQHandler           ; UART4
                DCD     UART5_IRQHandler           ; UART5
                DCD     TIM6_IRQHandler            ; TIM6
                DCD     TIM7_IRQHandler            ; TIM7
                DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1
                DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
                DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3
                DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
__Vectors_End		 ;向量表结束标志

__Vectors_Size  EQU  __Vectors_End - __Vectors		 		;得到向量表的大小 共76个中断向量,304个字节也就是0x130个字节

;地址重映射及中断向量表的转移 
               AREA    |.text|, CODE, READONLY    			;定义一个代码段,可读,段名字是.text  段名若以数字开头,则该段名需用"|"括起来,如|1_test|。 |.text|  表示由 C 编译程序产生的代码段,或用于以某种方式与 C 库关联的代码段。			
															;定义只读数据段,实际上是在CODE区,如果在FLASH区起动,则 中断向量起始地址为0X8000000

;复位向量处理函数
; Reset handler
Reset_Handler   PROC						 				;标记一个函数的开始;利用PROC、ENDP这一对伪指令把程序段分为若干个过程,使程序的结构加清晰
                EXPORT  Reset_Handler             [WEAK]    ;此处[WEAK]表示弱定义,优先执行其他文件的定义
                IMPORT  __main								;伪指令用于通知编译器要使用的标号在其他的源文件中定义
                IMPORT  SystemInit
                LDR     R0, =SystemInit						; 装载寄存器指令
                BLX     R0        				      		; 带链接的跳转,切换指令集。将处理器的工作状态由ARM状态切换到Thumb状态,该指令同时将PC的当前内容保存到寄存器R14中。因此,当子程序使用Thumb指令集,而调用者使用ARM指令集时,可以通过BLX指令实现子程序的调用和处理器工作状态的切换。同时,子程序的返回可以通过将寄存器R14值复制到PC中来完成。         
                LDR     R0, =__main					  		; 切换指令集,main函数不返回
                BX      R0									;BX指令跳转到指令中所指定的目标地址,目标地址处的指令既可以是ARM指令,也可以是Thumb指令。
                ENDP
        
;虚构的异常处理程序(可以修改的无限循环)        
; Dummy Exception Handlers (infinite loops which can be modified)

NMI_Handler     PROC
                EXPORT  NMI_Handler                [WEAK]
                B       .									; 死循环
                ENDP
HardFault_Handler\
                PROC
                EXPORT  HardFault_Handler          [WEAK]
                B       .									; 点“.”,它表示跳转到当前的指令地址处(即当前的 PC 值),也就是进入到当前的死循环中了。
                ENDP
MemManage_Handler\
                PROC
                EXPORT  MemManage_Handler          [WEAK]
                B       .
                ENDP
BusFault_Handler\
                PROC
                EXPORT  BusFault_Handler           [WEAK]
                B       .
                ENDP
UsageFault_Handler\
                PROC
                EXPORT  UsageFault_Handler         [WEAK]
                B       .
                ENDP
SVC_Handler     PROC
                EXPORT  SVC_Handler                [WEAK]
                B       .
                ENDP
DebugMon_Handler\
                PROC
                EXPORT  DebugMon_Handler           [WEAK]
                B       .
                ENDP
PendSV_Handler  PROC
                EXPORT  PendSV_Handler             [WEAK]
                B       .
                ENDP
SysTick_Handler PROC
                EXPORT  SysTick_Handler            [WEAK]
                B       .
                ENDP

Default_Handler PROC
 ; 输出异常向量表标号,方便外部实现异常的具体功能 , [WEAK] 是弱定义的意思,如果外部定义了,优先执行外部定义,否则执行下面的函数定义
                EXPORT  WWDG_IRQHandler            [WEAK]
                EXPORT  PVD_IRQHandler             [WEAK]
                EXPORT  TAMPER_IRQHandler          [WEAK]
                EXPORT  RTC_IRQHandler             [WEAK]
                EXPORT  FLASH_IRQHandler           [WEAK]
                EXPORT  RCC_IRQHandler             [WEAK]
                EXPORT  EXTI0_IRQHandler           [WEAK]
                EXPORT  EXTI1_IRQHandler           [WEAK]
                EXPORT  EXTI2_IRQHandler           [WEAK]
                EXPORT  EXTI3_IRQHandler           [WEAK]
                EXPORT  EXTI4_IRQHandler           [WEAK]
                EXPORT  DMA1_Channel1_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel2_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel3_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel4_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel5_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel6_IRQHandler   [WEAK]
                EXPORT  DMA1_Channel7_IRQHandler   [WEAK]
                EXPORT  ADC1_2_IRQHandler          [WEAK]
                EXPORT  USB_HP_CAN1_TX_IRQHandler  [WEAK]
                EXPORT  USB_LP_CAN1_RX0_IRQHandler [WEAK]
                EXPORT  CAN1_RX1_IRQHandler        [WEAK]
                EXPORT  CAN1_SCE_IRQHandler        [WEAK]
                EXPORT  EXTI9_5_IRQHandler         [WEAK]
                EXPORT  TIM1_BRK_IRQHandler        [WEAK]
                EXPORT  TIM1_UP_IRQHandler         [WEAK]
                EXPORT  TIM1_TRG_COM_IRQHandler    [WEAK]
                EXPORT  TIM1_CC_IRQHandler         [WEAK]
                EXPORT  TIM2_IRQHandler            [WEAK]
                EXPORT  TIM3_IRQHandler            [WEAK]
                EXPORT  TIM4_IRQHandler            [WEAK]
                EXPORT  I2C1_EV_IRQHandler         [WEAK]
                EXPORT  I2C1_ER_IRQHandler         [WEAK]
                EXPORT  I2C2_EV_IRQHandler         [WEAK]
                EXPORT  I2C2_ER_IRQHandler         [WEAK]
                EXPORT  SPI1_IRQHandler            [WEAK]
                EXPORT  SPI2_IRQHandler            [WEAK]
                EXPORT  USART1_IRQHandler          [WEAK]
                EXPORT  USART2_IRQHandler          [WEAK]
                EXPORT  USART3_IRQHandler          [WEAK]
                EXPORT  EXTI15_10_IRQHandler       [WEAK]
                EXPORT  RTCAlarm_IRQHandler        [WEAK]
                EXPORT  USBWakeUp_IRQHandler       [WEAK]
                EXPORT  TIM8_BRK_IRQHandler        [WEAK]
                EXPORT  TIM8_UP_IRQHandler         [WEAK]
                EXPORT  TIM8_TRG_COM_IRQHandler    [WEAK]
                EXPORT  TIM8_CC_IRQHandler         [WEAK]
                EXPORT  ADC3_IRQHandler            [WEAK]
                EXPORT  FSMC_IRQHandler            [WEAK]
                EXPORT  SDIO_IRQHandler            [WEAK]
                EXPORT  TIM5_IRQHandler            [WEAK]
                EXPORT  SPI3_IRQHandler            [WEAK]
                EXPORT  UART4_IRQHandler           [WEAK]
                EXPORT  UART5_IRQHandler           [WEAK]
                EXPORT  TIM6_IRQHandler            [WEAK]
                EXPORT  TIM7_IRQHandler            [WEAK]
                EXPORT  DMA2_Channel1_IRQHandler   [WEAK]
                EXPORT  DMA2_Channel2_IRQHandler   [WEAK]
                EXPORT  DMA2_Channel3_IRQHandler   [WEAK]
                EXPORT  DMA2_Channel4_5_IRQHandler [WEAK]
; 如下只是定义一个空函数,具体函数实现,需要用户在代码中实现。
WWDG_IRQHandler
PVD_IRQHandler
TAMPER_IRQHandler
RTC_IRQHandler
FLASH_IRQHandler
RCC_IRQHandler
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
DMA1_Channel1_IRQHandler
DMA1_Channel2_IRQHandler
DMA1_Channel3_IRQHandler
DMA1_Channel4_IRQHandler
DMA1_Channel5_IRQHandler
DMA1_Channel6_IRQHandler
DMA1_Channel7_IRQHandler
ADC1_2_IRQHandler
USB_HP_CAN1_TX_IRQHandler
USB_LP_CAN1_RX0_IRQHandler
CAN1_RX1_IRQHandler
CAN1_SCE_IRQHandler
EXTI9_5_IRQHandler
TIM1_BRK_IRQHandler
TIM1_UP_IRQHandler
TIM1_TRG_COM_IRQHandler
TIM1_CC_IRQHandler
TIM2_IRQHandler
TIM3_IRQHandler
TIM4_IRQHandler
I2C1_EV_IRQHandler
I2C1_ER_IRQHandler
I2C2_EV_IRQHandler
I2C2_ER_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
USART1_IRQHandler
USART2_IRQHandler
USART3_IRQHandler
EXTI15_10_IRQHandler
RTCAlarm_IRQHandler
USBWakeUp_IRQHandler
TIM8_BRK_IRQHandler
TIM8_UP_IRQHandler
TIM8_TRG_COM_IRQHandler
TIM8_CC_IRQHandler
ADC3_IRQHandler
FSMC_IRQHandler
SDIO_IRQHandler
TIM5_IRQHandler
SPI3_IRQHandler
UART4_IRQHandler
UART5_IRQHandler
TIM6_IRQHandler
TIM7_IRQHandler
DMA2_Channel1_IRQHandler
DMA2_Channel2_IRQHandler
DMA2_Channel3_IRQHandler
DMA2_Channel4_5_IRQHandler
                B       .

                ENDP

                ALIGN					 					; 默认是字对齐方式,也说明了代码是4字节对齐的		

;*******************************************************************************
; User Stack and Heap initialization      用户堆栈初始化
;*******************************************************************************
                 IF      :DEF:__MICROLIB       				;判断是否使用DEF:__MICROLIB(micro lib)在keil中选中 option--target--USE MicroLIB
                
                 EXPORT  __initial_sp		  				;使用的话则将栈顶地址,堆始末地址赋予全局属性使外部程序可以使用
                 EXPORT  __heap_base            			
                 EXPORT  __heap_limit
                
                 ELSE							  			;如果使用默认C库运行时
                
                 IMPORT  __use_two_region_memory   			;定义全局标号__use_two_region_memory
                 EXPORT  __user_initial_stackheap    		;声明全局标号__user_initial_stackheap,这样外部程序也可调用此标号,进行堆栈和堆的赋值,在__main函数执行过程中调用
                 
__user_initial_stackheap						  			;标号__user_initial_stackheap,表示用户堆栈初始化程序入口

                 LDR     R0, =  Heap_Mem					;保存堆始地址
                 LDR     R1, =(Stack_Mem + Stack_Size)		;保存栈的大小
                 LDR     R2, = (Heap_Mem +  Heap_Size)		;保存堆的大小
                 LDR     R3, = Stack_Mem					;保存栈顶指针
                 BX      LR									;LR连接寄存器,也就是R14,用于函数或者子程序调用返回地址的保存。 等同于 mov  pc,lr 即跳转到lr中存放的地址处

                 ALIGN										;设置对齐方式,在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐

                 ENDIF

                 END

;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE*****

下面开始对关键代码逐行分析

栈初始化:

要理解这三行代码,首先要了解下这几条汇编指令的含义

1、EQU

EQU定义栈空间的大小,栈空间由编译器自动分配变量所占内存,该汇编语句等效于#define Stack_Size 0x00000400。也就是在此处首先定义了栈的空间大小为 0x400,也就是1024个字节。

2、AREA

所以第二行代码作用是 :定义一个名为STACK的的内存单元,它是可读写的,对齐方式为2^3=8字节对齐

3、SPACE

第三行代码的含义就是,将刚才定义的STACK内存空间,全部初始化为0.

4、最后一行代码 __initial_sp 含义是初始化堆栈指针,并指向栈顶。

堆初始化:

1、EQU定义堆空间的大小(512字节),堆空间由人为手动分配变量所占内存,该汇编语句等效于#define Heap_Size 0x00000200

2、定义一个名为HEAP的内存单元,它是可读写的,对齐方式为2^3=8字节对齐

3、设置堆起始地址 

4、SPACE分配连续的堆存储空间,大小为0x00000200(512Bytes),把首地址赋给Heap_Mem

5、堆终止地址,与__heap_base配合限制堆的大小 

6、告诉编译器以8字节对齐,命令指定当前文件保持栈的八字节对齐

7、告诉编译器下面代码开始使用THUMB指令集,THUMB 必须位于使用新语法的任何Thumb代码之前;定义复位段(中断向量表),并初始化。

中断向量表定义:

中断向量表默认从地址0开始,如果使用了向量表重定位,则从重定位地址开始。假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000。

1、定义一个名为RESET的数据段,它是只读类型的。

2、声明全局变量_Vectors,该标号可在其他文件中使用,表示中断向量表入口地址

3、向量表终止地址

4、向量表空间大小

中断向量表入口地址:

 Top of Stack 第一个表项是栈顶地址;该处物理地址值即为 __Vetors 标号所表示的值;该地址中存储__initial_sp所表示的地址值。

依次给各个中断向量分配地址,分配后地址如下:

__Vectors_End 为向量表结束标志。

地址重映射及中断向量表的转移 :

         定义一个代码段,可读,段名字是.text  段名若以数字开头,则该段名需用"|"括起来,如|1_test|。 |.text|  表示由 C 编译程序产生的代码段,或用于以某种方式与 C 库关联的代码段。定义只读数据段,实际上是在CODE区,如果在FLASH区起动,则 中断向量起始地址为0X8000000。

复位向量处理函数:

        利用PROC、ENDP这一对伪指令把程序段分割,相当于C语言中的 {}作用。

       利用EXPORT 声明全局变量Reset_Handler,此处[WEAK]表示弱定义,假如程序中定义了Reset_Handler函数,就会执行用户定义的Reset_Handler函数,如果用户没有定义Reset_Handler函数,就执行当前函数。弱定义的含义就是当两个函数名相同时,优先执行用户定义的函数。

         这样是为了防止用户使能了中断而没有中断服务函数,从而造成程序崩溃。假设使能了中断,而用户又没有定义这个中断服务函数则会进入默认中断,默认中断为死循环。

利用IMPORT来声明main()函数和SystemInit()函数。

利用LDR命令,将函数SystemInit的地址加载到寄存器R0中。

通过BLX指令跳转到SystemInit()函数中。

接下来通过LDR指令装载main()函数地址。

通过BX指令,跳转到main()函数中。

虚构的异常处理程序:

输出异常向量表标号:

此处也使用了弱定义,如果外部定义了,优先执行外部定义,否则执行下面的函数定义。

实现弱定义函数:

实现各个中断函数,不过在这里中断函数都是空函数,没有具体实现,需要用户在代码中实现。

 用户堆栈初始化:

通过if和else来判断是否选择了微库

如果在keil中选择了USE MicroLIB 选项的话,就执行if语句,否则就执行else语句,使用默认的C库。

 IF      :DEF:__MICROLIB       				;判断是否使用DEF:__MICROLIB(micro lib)在keil中选中 option--target--USE MicroLIB
                
                 EXPORT  __initial_sp		  				;使用的话则将栈顶地址,堆始末地址赋予全局属性使外部程序可以使用
                 EXPORT  __heap_base            			
                 EXPORT  __heap_limit
                
                 ELSE							  			;如果使用默认C库运行时
                
                 IMPORT  __use_two_region_memory   			;定义全局标号__use_two_region_memory
                 EXPORT  __user_initial_stackheap    		;声明全局标号__user_initial_stackheap,这样外部程序也可调用此标号,进行堆栈和堆的赋值,在__main函数执行过程中调用
                 
__user_initial_stackheap						  			;标号__user_initial_stackheap,表示用户堆栈初始化程序入口

                 LDR     R0, =  Heap_Mem					;保存堆始地址
                 LDR     R1, =(Stack_Mem + Stack_Size)		;保存栈的大小
                 LDR     R2, = (Heap_Mem +  Heap_Size)		;保存堆的大小
                 LDR     R3, = Stack_Mem					;保存栈顶指针
                 BX      LR									;LR连接寄存器,也就是R14,用于函数或者子程序调用返回地址的保存。 等同于 mov  pc,lr 即跳转到lr中存放的地址处

                 ALIGN										;设置对齐方式,在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐

                 ENDIF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值