完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
第一部分:汇编指令学习
1.伪指令 1).EQU EQU伪指令:用来为一个数字常量、或一个和内核寄存器相关的数值或一个和程序计数器相关的数值定义的一个符号名称。类似于C语言中的#define 。 格式: name EQU expr{ , type} 格式: 名称 EQU 表达式(,类型) 例如: Stack_Size EQU 0X00000400 //定义1k字节的栈空间 Heap_Size EQU 0x00000200 //定义512字节的堆空间 2).AREA AREA伪指令:用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用“|”括起来,如:|1_test| 。 格式: AREA 段名 属性1 ,属性2 ,…… 属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。常用的属性如下: — CODE 属性:用于定义代码段,默认为READONLY 。 — DATA 属性:用于定义数据段,默认为READWRITE 。 — READONLY 属性:指定本段为只读,代码段默认为READONLY 。 — READWRITE 属性:指定本段为可读可写,数据段的默认属性为READWRITE 。 — ALIGN 属性:使用方式为ALIGN表达式。在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐的,表达式的取值范围为0~31,相应的对齐方式为2表达式次方。 — COMMON 属性:该属性定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的COMMON段共享同一段存储单元。 例如1: AREA HEAP, NOINIT, READWRITE, ALIGN=3 其中: HEAP: 定义一个堆段,名字 HEAP NOINIT: 只分配空间不初始化零 READWRITE:可以读写 ALIGN=3 : 8字节对齐 例如2: AREA STACK, NOINIT, READWRITE, ALIGN=3 定义一个栈段,名字是STACK,不初始化为0,可以读写,8字节对齐 例如3: AREA RESET, DATA, READONLY 定义一个数据段,名字是RESET,只可读;这里面的DATA属性表示RESET是一个数据段 例如4: AREA |.text|, CODE, READONLY 定义一个代码段,名字是 |.text|,只可读;这里面的CODE属性表示|.text|是一个代码段 3). SPACE SPACE伪指令:用于分配一片连续的存储单元并初始化为0,其中表达式为要分配的字节数 格式:标号 SPACE 表达式 1 2 例如1: Stack_Mem SPACE Stack_Size 分配连续Stack_Size 字节的存储单元,存储单元的名字是Stack_Mem,这里是在内存中连续分配1k字节的栈空间 例如2: Heap_Mem SPACE Heap_Size 分配连续Heap_Size 字节的存储单元,存储单元的名字是Heap_Mem,这里是在内存中连续分配512字节的堆空间 4). DCD(或DCDU) DCD伪指令:用于分配一片连续的字存储单元,并用伪指令中指定的表达式初始化。其中,表达式可以为程序标号或数字表达式。 DCD 也可用 “ & ” 代替。用 DCD 分配的字存储单元是字对齐的,而用 DCDU 分配的字存储单元并不严格字对齐。 格式:标号 DCD (或 DCDU ) 表达式 1 2 **例如1:**下面是摘自STM32f4启动代码的例子 其中:_Vectors是一个标号,该处的物理地址值即为 _Vetors 标号所表示的值,该地址中存储__initial_sp所表示的地址值。使用DCD定义了一个内存数组,数组首地址放置的是栈指针地址,然后是复位中断服务入口地址。这个表的作用的作用定义一个存放地址的数组表。 例如2: SwiFunction DCD TASK_SW DCD ENTER_CRITICAL DCD EXIT_CRITICAL DCD ISRBegin DCD ChangeToSYSMode DCD ChangeToUSRMode 5). ENTRY ENTRY伪指令用于指定汇编程序的入口点。 6).PROC/ENDP 过程就是子程序。一个程序可以被其他程序所调用(CALL),过程的最后一投指令一般反汇指令(RET),需要注意PROC和ENDP必须成对出现。 格式: <过程名> PROC [类型] ... ... ENDP 例如1:复位中断服务函数 Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP 例如2:硬件中断服务函数 HardFault_Handler PROC EXPORT HardFault_Handler [WEAK] B . ENDP 7).END END伪指令:用于指示汇编语言程序段结束,因此一个源程序中仅有一个END,且一般放在程序最后。若END放在程序中间,则END后面的语句将不再被汇编。 8).LDR、STR LDR指令:将存储器地址所指地址处连续的4个字节(1个字)的数据传送到目的寄存器中 STR指令:将寄存器内容存入内存空间中 格式: LDR{条件} 目的寄存器 <存储器地址> STR{条件} 源寄存器, <存储器地址> 例如1: LDR R0,[R1] ;将存储器地址为R1的字数据读入寄存器R0 LDR R0,[R1,R2] ;将存储器地址为R1+R2的字数据读入寄存器R0 LDR R0,[R1,#8] ;将存储器地址为R1+8的字数据读入寄存器R0 LDR R0,[R1],R2 ;将存储器地址为R1的字数据读入寄存器R0,然后R1=R1+8 LDR R0,[R1],#8 ;将存储器地址为R1的字数据读入寄存器R0,并将R1+8的值存入 LDR R0,=DATA ;将立即数DATA 加载到寄存器R0 STR R0,[R1],#8 ;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8 STR R1, [R0] ;将R1寄存器的值,传送到地址值为R0的(存储器)内存中 例如2: LDR R0, = Heap_Mem LDR R1, =(Stack_Mem + Stack_Size) LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem 2. 汇编指令 1). IMPORT 表示这是一个外部变量的标号,不是在本程序定义的,表明要调用的函数为外部文件定义 1 2).EXPORT 表示本程序里面用到的变量提供给其他模块调用的。 1 3).PRESERVE8 PRESERVE8指令指定当前文件需保持堆栈八字节对齐方式。其通过设置PRES8编译属性通知连接器。 1 格式: PRESERVE8 {bool} PRESERVE8 ;保持代码堆栈八字节对齐。 PRESERVE8 {FALSE} ;不保持代码堆栈八字节对齐。 4).Thumb Thumb是ARM体系结构中一种16位的指令集。Thumb指令集可以看作是ARM指令压缩形式的子集,它是为减小代码量而提出,具有16bit的代码密度。Thumb指令体系并不完整,只支持通用功能,必要时仍需要使用ARM指令,如进入异常时。其指令的格式与使用方式与ARM指令集类似,而且使用并不频繁,Thumb指令集作一般了解。 1 5).跳转指令B,BL,BX,BLX B Label ;跳转到Label处对应的地址 BL Label ;跳转到Label对应的地址,并且把跳转前的下条指令地址保存到LR BX reg ;跳转到由寄存器reg给出的地址 BLX reg ;跳转到由寄存器reg给出的地址,并根据REG的LSB切换处理器;状态还要把转移前的下条指令地址保存到LR. 其中BX 和BLX 都会启动中断返回序列。即从SP中依次将值返回至xPSR, PC, LR, R12以及R3-R0—-其中从堆栈SP中返回PC值实现了程序跳转。 对于B和BL 则是多用于函数跳转,其中BL保存了下条指令地址到LR. 6).IF——ELSE——ENDIF 格式: IF 判断式 执行1 ELSE 执行2 ENDIF 7).weak 一般来说,这个关键字使用在IMPORT和EXPORT这两个声明段,weak 声明其他的同名标号优先于该标号被引用。 IMPORT StackTop [WEAK] AREA |.text|, CODE, READONLY ;Vector list ARM_Vectors DCD StackTop IMORT: 如果我们有一个名为ARM_Vectors的量表,向量表的第一个数值指向一个StackTop函数的地址。因为我们可能定义了该函数,也可能没有,为了代码的简便,我们可以使用WEAK关键字。 当我们定义了StackTop函数后,那么ARM_Vectors里第一个向量值就是StackTop函数的地址。如果没有定义StackTop,那么编译器不会报错,而这时候第一个向量值就直接赋予0。 EXPORT: EXPORT的函数带有WEAK标志的话,并且别的源代码没有定义同名函数,那么连接时就是该函数;否则,就是另外的一个同名函数(类似类的继承) ———————————————— 版权声明:本文为CSDN博主「魔城烟雨」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/lixiaoweimashixiao/article/details/83042941 第二部分:STM32启动流程学习 1.基础知识储备 每一款芯片的启动文件都值得去研究,因为它是程序跑的最初一段代码。通过了解启动文件,我们可以体会到处理器的架构、指令集、中断向 量安排等内容,是非常值得研究的。 STM32作为一款高端Cortex-M3系列单片机,有必要了解它的启动文件。打好基础,为以后优化程序,写出高质量的代码最准备。 相对于ARM上一代的主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方式有了比较大的变化。ARM7/ARM9内核的控制器在复位后,CPU会从存储空间的绝对地址0x000000取出第一条指令执行复位中断服务程序的方式启动,即固定了复位后的起始地址为0x000000(PC = 0x000000)同时中断向量表的位置并不是固定的。而Cortex-M3内核则正好相反,有3种情况: 1、 通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处;2、 通过boot引脚设置可以将中断向量表定位于FLASH区,即起始地址为0x8000000,同时复位后PC指针位于0x8000000处;3、 通过boot引脚设置可以将中断向量表定位于内置Bootloader区,本文不对这种情况做论述;** 而Cortex-M3内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。对比ARM7/ARM9内核,Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。 STM整个启动过程是指从上电开始,一直到运行到main函数之间的这段过程,步骤为: ①上电后硬件设置SP、PC②设置系统时钟③软件设置SP④加载.data、.bss,并初始化栈区⑤跳转到C文件的main函数 启动过程涉及的文件不仅包含startup_stm32f40x_hd.s,还涉及到了MDK自带的连接库文件entry.o、entry2.o、entry5.o、entry7.o等(从生成的map文件可以看出来)。 2.反汇编工具 STM32启动代码startup_stm32f40_41xxx.s,这里以天穹飞控代码的启动进行反汇编分析。使用的反汇编工具是IDAIDA下载地址,对应的密码是a2mm,怎么使用的这里就不做讲述,可以自行查资料。界面下图所示。 **步骤: 直接点击OK,然后Go,继续File选择open,选择BlueSky.axf(这里可以随意打开电脑上的一个.exe文件,主要学会使用这个软件)**打开之后主要出现IDA View-A,Hex View-1 ,Structures ,Enums,Imports,Exports这些窗口 整体界面显示: (1)IDA View-A 这个就是启动代码如何运行到main()函数的流程图 也可以参考这个博客:如何到main()函数 (2)Hex View-1 **(3)Structures ** (4)Enums (5)Exports 第三部分:STM32启动代码分析 Stack_Size EQU 0x00000400 ;EQU伪指令,作用是左边的符号名代表右边的表达式 AREA STACK, NOINIT, READWRITE, ALIGN=3 ;定义栈段:名称为STACK,未初始化,可读写,ELF 的栈段按2^3=8对齐 Stack_Mem SPACE Stack_Size ;分配一片连续的存储区域并初始化为 0,栈空间:0x400个字节 __initial_sp ;栈空间顶地址 ; ; ; Heap_Size EQU 0x00000200 AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base ;堆空间起始地址 Heap_Mem SPACE Heap_Size ;堆空间:0x200个字节 __heap_limit ;堆空间结束地址 PRESERVE8 ;PRESERVE8 指令指定当前文件保持堆栈八字节对齐 THUMB ;告诉汇编器下面是32位的Thumb指令,如果需要汇编器将插入位以保证对齐 ; Vector Table Mapped to Address 0 at Reset ;中断向量表定义 ;实际上是在CODE区(假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000) AREA RESET, DATA, READONLY ;定义一块数据段,只可读 EXPORT __Vectors ;EXPORT:在程序中声明一个全局的标号__Vectors,该标号可在其他的文件中引用 EXPORT __Vectors_End ;在程序中声明一个全局的标号__Vectors_End EXPORT __Vectors_Size ;在程序中声明一个全局的标号__Vectors_Size ;DCD(DCDU)用于分配一片连续的字存储单元并用指定的数据初始化。 __Vectors DCD __initial_sp ; Top of Stack ;该处物理地址值存储__initial_sp所表示的地址值,即为 __Vetors 标号所表示的值 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 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 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结束 __Vectors_Size EQU __Vectors_End - __Vectors ;得到向量表的大小,304个字节也就是0x130个字节 AREA |.text|, CODE, READONLY ;定义一个代码段,可读,段名字是.text ;|.text| 用于表示由 C 编译程序产生的代码段,或用于以某种方式与 C 库关联的代码段 ; Reset handler ;利用PROC、ENDP这一对伪指令标记程序开始、结束,把程序段分为若干个过程,使程序的结构加清晰 Reset_Handler PROC EXPORT Reset_Handler [WEAK];WEAK声明其他的同名标号优先于该标号被引用,就是说如果外面声明了的话,调用外面的对应函数 IMPORT __main ;IMPORT:伪指令用于通知编译器要使用的标号在其他的源文件中定义 IMPORT SystemInit LDR R0, =SystemInit ;系统初始化 BLX R0 ;带链接的跳转,切换指令集,跳到SystemInit LDR R0, =__main ;__main为运行时库提供的函数;完成堆栈,堆的初始化等工作,会调用下面定义的__user_initial_stackheap BX R0 ;切换指令集,main函数不返回跳到__main,进入C的世界 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 . 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 ;默认是字对齐方式 ;******************************************************************************* ; User Stack and Heap initialization 用户堆栈初始化 ;******************************************************************************* IF :DEF:__MICROLIB ;判断是否使用DEF:__MICROLIB(micro lib),如果勾选了micro lib EXPORT __initial_sp ;将栈顶地址、堆起始地址、堆结束地址赋予全局属性,使外部程序可用 EXPORT __heap_base EXPORT __heap_limit ELSE ;如果没有勾选micro lib IMPORT __use_two_region_memory ;两区堆栈空间,堆和栈有各自的空间地址 EXPORT __user_initial_stackheap __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 ALIGN ENDIF END ;END命令指示汇编器,已到达一个源文件的末尾 ;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE***** |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1752 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1611 浏览 1 评论
1052 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1666 浏览 2 评论
1926浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
711浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
560浏览 3评论
584浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
544浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 21:16 , Processed in 0.798029 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号