热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

启动文件源码如下:;Amountofmemory(inbytes)allocatedforStack;Tailorthisvaluetoyourapplicati

启动文件源码如下:

; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; Stack Configuration
; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
;栈初始化
Stack_Size EQU 0x00000400 ;EQU定义栈空间的大小 1024字节&#xff0c;栈空间由编译器自动分配变量所占内存&#xff0c;该汇编语句等效于#define Stack_Size 0x00000400AREA STACK, NOINIT, READWRITE, ALIGN&#61;3 ;定义一个名为STACK的内存单元&#xff0c;它是可读写的&#xff0c;对齐方式为2^3&#61;8字节对齐
Stack_Mem SPACE Stack_Size ;SPACE分配连续的栈存储空间&#xff0c;大小为0x00000400(1K)&#xff0c;把首地址赋给Stack_Mem
__initial_sp ;初始化堆栈指针&#xff0c;指向堆栈顶。; Heap Configuration
; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
;堆初始化
Heap_Size EQU 0x00000200 ;EQU定义堆空间的大小&#xff0c;堆空间由人为手动分配变量所占内存&#xff0c;该汇编语句等效于#define Heap_Size 0x00000200AREA HEAP, NOINIT, READWRITE, ALIGN&#61;3 ;定义一个名为HEAP的内存单元&#xff0c;它是可读写的&#xff0c;对齐方式为2^3&#61;8字节对齐
__heap_base ;堆起始地址
Heap_Mem SPACE Heap_Size ;SPACE分配连续的堆存储空间&#xff0c;大小为0x00000200(512Bytes)&#xff0c;把首地址赋给Heap_Mem
__heap_limit ;堆终止地址&#xff0c;与__heap_base配合限制堆的大小 PRESERVE8 ;告诉编译器以8字节对齐&#xff0c;命令指定当前文件保持栈的八字节对齐THUMB ;告诉编译器使用THUMB指令集&#xff0c;THUMB 必须位于使用新语法的任何Thumb代码之前;定义复位段&#xff08;中断向量表&#xff09;&#xff0c;并初始化;中断向量表定义
; Vector Table Mapped to Address 0 at Reset ;中断向量表默认从地址0开始&#xff0c;如果使用了向量表重定位&#xff0c;则从重定位地址开始。假设STM32从FLASH启动&#xff0c;则此中断向量表起始地址即为0x8000000。AREA RESET, DATA, READONLY ;定义一个名为RESET的数据段&#xff0c;它是只读类型的。EXPORT __Vectors ;声明全局变量_Vectors&#xff0c;该标号可在其他文件中使用&#xff0c;表示中断向量表入口地址EXPORT __Vectors_End ;向量表终止地址EXPORT __Vectors_Size ;向量表空间大小__Vectors DCD __initial_sp ; Top of Stack Top of Stack 第一个表项是栈顶地址;该处物理地址值即为 __Vetors 标号所表示的值;该地址中存储__initial_sp所表示的地址值&#xff0c;
;大小为一个字&#xff08;32bit&#xff09; DCD Reset_Handler ; Reset Handler 复位异常&#xff0c;装载完栈顶后&#xff0c;第一个执行的&#xff0c;并且不返回。DCD NMI_Handler ; NMI Handler 不可屏蔽中断DCD HardFault_Handler ; Hard Fault Handler 硬件错误中断DCD MemManage_Handler ; MPU Fault Handler 内存管理错误中断DCD BusFault_Handler ; Bus Fault Handler 总线错误中断&#xff0c;一般发生在数据访问异常&#xff0c;比如fsmc访问不当DCD UsageFault_Handler ; Usage Fault Handler 用法错误中断&#xff0c;一般是预取值&#xff0c;或者位置指令&#xff0c;数据处理等错误DCD 0 ; ReservedDCD 0 ; ReservedDCD 0 ; ReservedDCD 0 ; ReservedDCD SVC_Handler ; SVCall Handler 系统调用异常&#xff0c;主要是为了调用操作系统内核服务DCD DebugMon_Handler ; Debug Monitor Handler 调试监视异常DCD 0 ; ReservedDCD PendSV_Handler ; PendSV Handler 挂起异常&#xff0c;此处可以用作RTOS的上下文切换异常&#xff0c;这是被推荐使用的&#xff0c;因为Cortex-M4会在异常发生时自动保存R0-R3&#xff0c;R12,R13(堆栈指针SP)&#xff0c;R14(链接地址&#xff0c;也叫返回地址LR&#xff0c;在异常返回时使用)&#xff0c;R15&#xff08;程序计数器PC&#xff0c;为当前应用程序&#43;4&#xff09;和中断完成时自动恢复&#xff0c;我们只需保存R4-R11,大大减少了中断响应和上下文切换的时间。DCD SysTick_Handler ; SysTick Handler 滴答定时器&#xff0c;为操作系统内核时钟; External Interrupts 外部中断DCD WWDG_IRQHandler ; Window WatchdogDCD PVD_IRQHandler ; PVD through EXTI Line detectDCD TAMPER_IRQHandler ; TamperDCD RTC_IRQHandler ; RTCDCD FLASH_IRQHandler ; FlashDCD RCC_IRQHandler ; RCCDCD EXTI0_IRQHandler ; EXTI Line 0DCD EXTI1_IRQHandler ; EXTI Line 1DCD EXTI2_IRQHandler ; EXTI Line 2DCD EXTI3_IRQHandler ; EXTI Line 3DCD EXTI4_IRQHandler ; EXTI Line 4DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7DCD ADC1_2_IRQHandler ; ADC1 & ADC2DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TXDCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0DCD CAN1_RX1_IRQHandler ; CAN1 RX1DCD CAN1_SCE_IRQHandler ; CAN1 SCEDCD EXTI9_5_IRQHandler ; EXTI Line 9..5DCD TIM1_BRK_IRQHandler ; TIM1 BreakDCD TIM1_UP_IRQHandler ; TIM1 UpdateDCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and CommutationDCD TIM1_CC_IRQHandler ; TIM1 Capture CompareDCD TIM2_IRQHandler ; TIM2DCD TIM3_IRQHandler ; TIM3DCD TIM4_IRQHandler ; TIM4DCD I2C1_EV_IRQHandler ; I2C1 EventDCD I2C1_ER_IRQHandler ; I2C1 ErrorDCD I2C2_EV_IRQHandler ; I2C2 EventDCD I2C2_ER_IRQHandler ; I2C2 ErrorDCD SPI1_IRQHandler ; SPI1DCD SPI2_IRQHandler ; SPI2DCD USART1_IRQHandler ; USART1DCD USART2_IRQHandler ; USART2DCD USART3_IRQHandler ; USART3DCD EXTI15_10_IRQHandler ; EXTI Line 15..10DCD RTCAlarm_IRQHandler ; RTC Alarm through EXTI LineDCD USBWakeUp_IRQHandler ; USB Wakeup from suspendDCD TIM8_BRK_IRQHandler ; TIM8 BreakDCD TIM8_UP_IRQHandler ; TIM8 UpdateDCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and CommutationDCD TIM8_CC_IRQHandler ; TIM8 Capture CompareDCD ADC3_IRQHandler ; ADC3DCD FSMC_IRQHandler ; FSMCDCD SDIO_IRQHandler ; SDIODCD TIM5_IRQHandler ; TIM5DCD SPI3_IRQHandler ; SPI3DCD UART4_IRQHandler ; UART4DCD UART5_IRQHandler ; UART5DCD TIM6_IRQHandler ; TIM6DCD TIM7_IRQHandler ; TIM7DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
__Vectors_End ;向量表结束标志__Vectors_Size EQU __Vectors_End - __Vectors ;得到向量表的大小 共76个中断向量,304个字节也就是0x130个字节;地址重映射及中断向量表的转移 AREA |.text|, CODE, READONLY ;定义一个代码段&#xff0c;可读&#xff0c;段名字是.text 段名若以数字开头&#xff0c;则该段名需用"|"括起来&#xff0c;如|1_test|。 |.text| 表示由 C 编译程序产生的代码段&#xff0c;或用于以某种方式与 C 库关联的代码段。 ;定义只读数据段&#xff0c;实际上是在CODE区&#xff0c;如果在FLASH区起动&#xff0c;则 中断向量起始地址为0X8000000;复位向量处理函数
; Reset handler
Reset_Handler PROC ;标记一个函数的开始;利用PROC、ENDP这一对伪指令把程序段分为若干个过程&#xff0c;使程序的结构加清晰EXPORT Reset_Handler [WEAK] ;此处[WEAK]表示弱定义&#xff0c;优先执行其他文件的定义IMPORT __main ;伪指令用于通知编译器要使用的标号在其他的源文件中定义IMPORT SystemInitLDR R0, &#61;SystemInit ; 装载寄存器指令BLX R0 ; 带链接的跳转&#xff0c;切换指令集。将处理器的工作状态由ARM状态切换到Thumb状态&#xff0c;该指令同时将PC的当前内容保存到寄存器R14中。因此&#xff0c;当子程序使用Thumb指令集&#xff0c;而调用者使用ARM指令集时&#xff0c;可以通过BLX指令实现子程序的调用和处理器工作状态的切换。同时&#xff0c;子程序的返回可以通过将寄存器R14值复制到PC中来完成。 LDR R0, &#61;__main ; 切换指令集,main函数不返回BX R0 ;BX指令跳转到指令中所指定的目标地址&#xff0c;目标地址处的指令既可以是ARM指令&#xff0c;也可以是Thumb指令。ENDP;虚构的异常处理程序(可以修改的无限循环)
; Dummy Exception Handlers (infinite loops which can be modified)NMI_Handler PROCEXPORT NMI_Handler [WEAK]B . ; 死循环ENDP
HardFault_Handler\PROCEXPORT HardFault_Handler [WEAK]B . ; 点“.”,它表示跳转到当前的指令地址处&#xff08;即当前的 PC 值&#xff09;&#xff0c;也就是进入到当前的死循环中了。ENDP
MemManage_Handler\PROCEXPORT MemManage_Handler [WEAK]B .ENDP
BusFault_Handler\PROCEXPORT BusFault_Handler [WEAK]B .ENDP
UsageFault_Handler\PROCEXPORT UsageFault_Handler [WEAK]B .ENDP
SVC_Handler PROCEXPORT SVC_Handler [WEAK]B .ENDP
DebugMon_Handler\PROCEXPORT DebugMon_Handler [WEAK]B .ENDP
PendSV_Handler PROCEXPORT PendSV_Handler [WEAK]B .ENDP
SysTick_Handler PROCEXPORT SysTick_Handler [WEAK]B .ENDPDefault_Handler PROC; 输出异常向量表标号&#xff0c;方便外部实现异常的具体功能 &#xff0c; [WEAK] 是弱定义的意思&#xff0c;如果外部定义了&#xff0c;优先执行外部定义&#xff0c;否则执行下面的函数定义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]
; 如下只是定义一个空函数,具体函数实现&#xff0c;需要用户在代码中实现。
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_IRQHandlerB .ENDPALIGN ; 默认是字对齐方式&#xff0c;也说明了代码是4字节对齐的 ;*******************************************************************************
; User Stack and Heap initialization 用户堆栈初始化
;*******************************************************************************IF :DEF:__MICROLIB ;判断是否使用DEF:__MICROLIB&#xff08;micro lib&#xff09;在keil中选中 option--target--USE MicroLIBEXPORT __initial_sp ;使用的话则将栈顶地址&#xff0c;堆始末地址赋予全局属性使外部程序可以使用EXPORT __heap_base EXPORT __heap_limitELSE ;如果使用默认C库运行时IMPORT __use_two_region_memory ;定义全局标号__use_two_region_memoryEXPORT __user_initial_stackheap ;声明全局标号__user_initial_stackheap&#xff0c;这样外部程序也可调用此标号&#xff0c;进行堆栈和堆的赋值&#xff0c;在__main函数执行过程中调用__user_initial_stackheap ;标号__user_initial_stackheap&#xff0c;表示用户堆栈初始化程序入口LDR R0, &#61; Heap_Mem ;保存堆始地址LDR R1, &#61;(Stack_Mem &#43; Stack_Size) ;保存栈的大小LDR R2, &#61; (Heap_Mem &#43; Heap_Size) ;保存堆的大小LDR R3, &#61; Stack_Mem ;保存栈顶指针BX LR ;LR连接寄存器&#xff0c;也就是R14&#xff0c;用于函数或者子程序调用返回地址的保存。 等同于 mov pc,lr 即跳转到lr中存放的地址处ALIGN ;设置对齐方式&#xff0c;在默认时&#xff0c;ELF&#xff08;可执行连接文件&#xff09;的代码段和数据段是按字对齐ENDIFEND;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE*****

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

栈初始化&#xff1a;

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

1、EQU

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

2、AREA

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

3、SPACE

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

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

堆初始化&#xff1a;

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

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

3、设置堆起始地址 

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

5、堆终止地址&#xff0c;与__heap_base配合限制堆的大小 

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

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

中断向量表定义&#xff1a;

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

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

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

3、向量表终止地址

4、向量表空间大小

中断向量表入口地址&#xff1a;

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

依次给各个中断向量分配地址&#xff0c;分配后地址如下&#xff1a;

__Vectors_End 为向量表结束标志。

地址重映射及中断向量表的转移 &#xff1a;

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

复位向量处理函数&#xff1a;

        利用PROC、ENDP这一对伪指令把程序段分割&#xff0c;相当于C语言中的 &#xff5b;&#xff5d;作用。

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

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

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

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

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

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

通过BX指令&#xff0c;跳转到main()函数中。

虚构的异常处理程序&#xff1a;

输出异常向量表标号&#xff1a;

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

实现弱定义函数&#xff1a;

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

 用户堆栈初始化:

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

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

IF :DEF:__MICROLIB ;判断是否使用DEF:__MICROLIB&#xff08;micro lib&#xff09;在keil中选中 option--target--USE MicroLIBEXPORT __initial_sp ;使用的话则将栈顶地址&#xff0c;堆始末地址赋予全局属性使外部程序可以使用EXPORT __heap_base EXPORT __heap_limitELSE ;如果使用默认C库运行时IMPORT __use_two_region_memory ;定义全局标号__use_two_region_memoryEXPORT __user_initial_stackheap ;声明全局标号__user_initial_stackheap&#xff0c;这样外部程序也可调用此标号&#xff0c;进行堆栈和堆的赋值&#xff0c;在__main函数执行过程中调用__user_initial_stackheap ;标号__user_initial_stackheap&#xff0c;表示用户堆栈初始化程序入口LDR R0, &#61; Heap_Mem ;保存堆始地址LDR R1, &#61;(Stack_Mem &#43; Stack_Size) ;保存栈的大小LDR R2, &#61; (Heap_Mem &#43; Heap_Size) ;保存堆的大小LDR R3, &#61; Stack_Mem ;保存栈顶指针BX LR ;LR连接寄存器&#xff0c;也就是R14&#xff0c;用于函数或者子程序调用返回地址的保存。 等同于 mov pc,lr 即跳转到lr中存放的地址处ALIGN ;设置对齐方式&#xff0c;在默认时&#xff0c;ELF&#xff08;可执行连接文件&#xff09;的代码段和数据段是按字对齐ENDIF


推荐阅读
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • 原文地址http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/最开始时 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文介绍了在win7电脑上进行文件加密的方法,包括利用NTFS的EFS进行加密和使用Win7旗舰版的Bitlocker加密整个分区。同时推荐了超级加密3000、宏杰加密工具和超级盘加密工具等多种加密软件,这些软件具有快速的加密速度和高强度的加密功能,可以防止文件的删除、复制和移动。此外,还强调了保持加密密钥的重要性,以免重装系统后无法打开已加密的文件。最后,提醒读者选择绿色软件,方便使用。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 初探PLC 的ST 语言转换成C++ 的方法
    自动控制软件绕不开ST(StructureText)语言。它是IEC61131-3标准中唯一的一个高级语言。目前,大多数PLC产品支持ST ... [详细]
  • qt学习(六)数据库注册用户的实现方法
    本文介绍了在qt学习中实现数据库注册用户的方法,包括登录按钮按下后出现注册页面、账号可用性判断、密码格式判断、邮箱格式判断等步骤。具体实现过程包括UI设计、数据库的创建和各个模块调用数据内容。 ... [详细]
  • 本文介绍了使用SRILM平滑Katz回退方法训练语言模型的步骤,包括测试文件的使用、模型训练过程以及困惑度的重新计算。平滑Katz回退方法通过将次数较少的N-gram组的概率减少,并将减少的概率分配给训练集中未出现的N-gram组。详细的条件概率计算过程可参考附录中的Excel表格。通过重新计算困惑度,可以评估训练得到的语言模型的质量。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
  • AFNetwork框架(零)使用NSURLSession进行网络请求
    本文介绍了AFNetwork框架中使用NSURLSession进行网络请求的方法,包括NSURLSession的配置、请求的创建和执行等步骤。同时还介绍了NSURLSessionDelegate和NSURLSessionConfiguration的相关内容。通过本文可以了解到AFNetwork框架中使用NSURLSession进行网络请求的基本流程和注意事项。 ... [详细]
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
author-avatar
灰包蛋啦_199
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有