本文通过对STM32的官方固件库STM32F10x_StdPeriph_Lib_V3.5.0
里的MDK启动文件分析,简化部分不需要的代码,并从繁杂的固件库里,精炼出一个类似于“hello world”的入门实战小程序——点亮一个LED。该工程仅仅包含一个启动文件和一个有main函数的C文件。
本文初衷:不用固件库建立自己的工程!
实验软件:Keil uVision4 实验硬件:神舟IV号开发板
芯片型号:STM32F107VC
STM32启动代码分析、简化、实战
汇编基础:
1. 伪指令:EQU
语法格式:名称 EQU 表达式{,类型} EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于C语言的#define。其中EQU可以用“*”代替。
名称为EQU伪指令定义的字符名称,当表达式为32位的常量时,可以指定表达式的数据类型,可以有一下三种类型: CODE16、CODE32和DATA
2. 伪指令:AREA
语法格式:AREA 段名{,属性1}{,属性2}……
AREA命令指示汇编程序汇编一个新的代码段或数据段。段是独立的、指定的、不可见的代码或数据块,它们由链接程序处理。
段名:可以为段选择任何段名。但是,以一个数字开始的名称必须包含在竖杠号内,否则会产生一个缺失段名错误。例如,|1_DataArea|。
有些名称是习惯性的名称。例如:|.text|用于表示由C编译程序产生的代码段,或用于以某种方式与C库关联的代码段。
属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。常用的属性如下: ——CODE属性:用于定义代码段,默认为READONLY。 ——DATA属性:用于定义数据段,默认为READWRITE。
——READONLY属性:指定本段为只读,代码段默认为READONLY。
——READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE。 ——ALIGN属性:使用方式为ALIGN表达式。在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐的,表达式的取值范围为0~31,相应的对齐方式为2表达式次方。 ——NOINIT属性:表示数据段是未初始化的或初始化为零。其只包含零初始化的空间保留命令SPACE或DCB、DCD、DCDU、DCQ、DCQU、DCW或DCWU。可以决定在链接时AREA是未初始化的还是零初始化的。 一个汇编语言程序至少要包含一个段,当程序太长时,也可以将程序分为多个代码段和数据段。
3. 伪指令:SPACE
启动代码分析:
用于分配一片连续的存储单元
定义栈段,不初始化
栈名:STACK 大小:Stack_Size
只分配空间不做初始化或者初始化为0:NOINIT 可读可写:READWRITE: 按8字节对齐:ALIGN=3 栈顶地址:__initial_sp Stack_Size
EQU AREA SPACE
0x00000400
STACK, NOINIT, READWRITE, ALIGN=3 Stack_Size
Stack_Mem __initial_sp
定义堆段,不初始化
堆名:HEAP 大小:Heap_Size
只分配空间不做初始化或者初始化为0:NOINIT 可读可写:READWRITE: 按8字节对齐:ALIGN=3 堆起始地址:__heap_base 堆终止地址:__heap_limit Heap_Size
EQU AREA
0x00000200
HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base Heap_Mem SPACE Heap_Size __heap_limit
4. 伪指令:EXPORT
语法格式:EXPORT 标号{[WEAK]}
EXPORT伪指令用于在程序中声明一个全局的标号,该标号可在其他的文件中引用。EXPORT可用GLOBAL代替。标号在程序中区分大小写,[WEAK]选项声明其他的同名标号优先于该标号被引用。
5. 伪指令:DCD
语法格式:DCD(或DCDU) 表达式
DCD(或DCDU)伪指令用于分配一片连续的字存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为程序标号或数字表达式。DCD也可用“&”代替。
用DCD分配的字存储单元是字对齐的,而用DCDU分配的字存储单元并不严格字对齐。 PRESERVE8 ;指示编译器8字节对齐(keil编译器时需要加上) THUMB ;指示编译器为THUMB指令
定义复位段(中断向量表),并初始化
段名:RESET 大小:__Vectors_Size 数据段:DATA
只读:READONLY
按字节对齐:默认ALIGN 向量表起始地址:__Vectors 向量表终止地址:__Vectors_End
AREA RESET, DATA, READONLY EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size __Vectors DCD __initial_sp ; Top of Stack 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 and ADC2 DCD CAN1_TX_IRQHandler ; CAN1 TX DCD CAN1_RX0_IRQHandler ; 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 ; I2C1 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 OTG_FS_WKUP_IRQHandler ; USB OTG FS DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved 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_IRQHandler ; DMA2 Channel4 DCD DMA2_Channel5_IRQHandler ; DMA2 Channel5 DCD ETH_IRQHandler ; Ethernet
DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line DCD CAN2_TX_IRQHandler ; CAN2 TX DCD CAN2_RX0_IRQHandler ; CAN2 RX0 DCD CAN2_RX1_IRQHandler ; CAN2 RX1 DCD CAN2_SCE_IRQHandler ; CAN2 SCE DCD OTG_FS_IRQHandler ; USB OTG FS __Vectors_End __Vectors_Size EQU __Vectors_End - __Vectors 6. 过程定义伪指令:PROC、ENDP 语法格式:<过程名> PROC [类型] …… RET <过程名> ENDP
过程就是子程序。一个过程可以被其它程序所调用(用CALL指令),过程的最后一条指令一