代码见CSDN链接为:
编译环境为Keil5,
烧写的bin文件,烧写的区域为STM32F103ZET6内部的ROM
内部的ROM地址为0x08000000
LED.bin
Code 代表执行的代码,程序中所有的函数都位于此处。
RO-data 代表只读数据,程序中所定义的全局常量数据和字符串都位于此处
RW-data 代表已初始化的读写数据,程序中定义并且初始化的全局变量和静态变量位于此处。
ZI-data 代表未初始化的读写数据,程序中定义了但没有初始化的全局变量和静态变量位于此处。
ZI英语是zero initial,就是程序中用到的变量并且被系统初始化为0的变量的字节数,
keil编译器默认是把你没有初始化的变量都赋值一个0,这些变量在程序运行时是保存在RAM中的。
程序的大小为0x288字节,648字节
以上可以了解到,LED.bin文件是下载到STM32ZET6的0x08000000~0x08000280处,
map文件使用微库的映射
内存映射的图像
这里使用了Mircro LIB
CPU从Reset_Handler=0x0800017f处执行,MSP=0x2000400.
启动文件分析 startup_stm32f10x_hd.s
1、Stack-栈
Stack_Size EQU 0x00000800
;EQU 宏定义的未定义,相当于C中的define
AREA STACK, NOINIT, READWRITE, ALIGN=3
;AREA 告诉汇编器编译一个新的代码段或者数据段,STACK 表明段名,这个可以任意命名;
;NOINIT 表示不初始化,READWRITE 表示可读可写,ALIGN=3,表示8字节对齐
Stack_Mem SPACE Stack_Size
;SPACE 用于分配一定的内存空间,单位字节,指定大小为Stack_Size
__initial_sp
;__initial_sp 紧挨着SPACE语句放置,表示栈的结束地址,栈顶地址,栈由高向低生长,
__initial_sp=0x20000800
__initial_spTop EQU 0x20000400 ; stack used for SystemInit_ExtMemCtl
; always internal RAM used
;在0x20000400处的位置为__initial_spTop
;此段为名词为STACK段,大小为0x800
; Heap Configuration
; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
2、Heap-堆
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base
;__heap_base 表示堆的起始地址,,
Heap_Mem SPACE Heap_Size
__heap_limit
;__heap_limit 表示堆的结束地址,
;堆主要用来动态内存分配,像malloc()函数申请的内存就在堆上,
;以上的代码段名词为HEAP,大小为0
PRESERVE8
THUMB
;PERSERVE8 指定当前文件的堆栈按照8字节对齐
; THUMB表示后面指令兼容THUMB指令,
3、 向量表
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
;定义一个数据区(实则为startup_stm32f10x_hd.o 数据区名称为RESET(在内存映射的图像)),
;RESET可读,声明__Vectors,__Vectors_End和__Vectors_Size三个标号,三个标号具有全局属性,可以供外部文件调用,
EXPORT:声明一个标号可被外部文件使用,标号具有全局属性,如果是IAR编译器,则使用GLOBAL
当内核响应了一个发生的异常后,对应的异常服务例程(ESR)就会执行。为了决定 ESR的入口地址, 内核使用了―向量表查表机制‖。这里使用一张向量表。向量表其实是一个WORD(32 位整数)数组,每个下标对应一种异常,该下标元素的值则是该 ESR 的入口地址。向量表在地址空间中的位置是可以设置的,通过 NVIC 中的一个重定位寄存器来指出向量表的地址。在复位后,该寄存器的值为 0。因此,在地址 0 (即 FLASH 地址 0) 处必须包含一张向量表,用于初始时的异常分配。要注意的是这里有个另类: 0 号类型并不是什么入口地址,而是给出了复位后 MSP 的初值。
F103向量表
__Vectors DCD __initial_spTop ; Top of Stack ;栈顶地址0x200004000
;__Vectors 向量的其实地址,在STM32ZET6,__Vectors=0x08000000
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
;DCD:分配一个或者多个以字为单位的内存,以四字节对齐,并要求初始化这些内存。在向量表中, DCD 分配了一堆内存;
__Vectors_End
;__Vectors_End=0x0800012c
__Vectors_Size EQU __Vectors_End - __Vectors
;__Vectors_Size =0x0800012c-0x08000000=0x12c;
;以上的代码段名词为RESET,范围为0x08000000~0x0800012c,大小为0x00000130
AREA |.text|, CODE, READONLY
;同理上文可知text代码段 可读
; Dummy SystemInit_ExtMemCtl function
SystemInit_ExtMemCtl PROC
EXPORT SystemInit_ExtMemCtl [WEAK]
BX LR
ENDP
SystemInit_ExtMemCtl区域SystemInit_ExtMemCtl=0x0800017c
标记__weak 或 [weak]的函数 就是用在本文件占位的,如果别的文件重写的这个函数就用别文件的,否则使用本文件的。加上了 [WEAK] 修饰. 用户可以根据自己的需要重新编写自己的处理函数, 而且只要命名一样就 OK 了. ( WEAK:表示弱定义,如果外部文件优先定义了该标号则首先引用该标号,如果外部文件没有声明也不会出错。这里表示复位子程序可以由用户在其他文件重新实现,这里并不是唯一的。)
;利用PROC、ENDP这一对伪指令把程序段分为若干个部分
; Reset handler routine
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT:表示该标号来自外部文件,跟 C 语言中的 EXTERN 关键字类似。这里__main 这两个函数均来自外部的文件。
LDR R0, = SystemInit_ExtMemCtl ; initialize external memory controller
BLX R0
;BLX挑战到寄存器值得地址,并把跳转前的下一个指令的地址保存到lr寄存器中,
LDR R1, = __initial_sp ; restore original stack pointer
ldr;将存储器中加载字到一个寄存器中,
MSR MSP, R1
LDR R0, =__main ;
这里的__main和c文件的main是不同的地址,__main来自于编译器中
这里的__main=0x08000130
BX R0
;跳到寄存器值得地址,
ENDP
;这里存储的区域是编译器的__main,因为__main会条用外部的main,
__main区域 __main=0x08000130
…(因为__main会调用其他代码用…)
main.o区域
因为main条用了led.o
led.o区域 led=0x08000144
Stm32_Clock_Init.o区域 Stm32_Clock_Init=0x080001d0
; 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
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=0x0800019e
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 ALIGN:对指令或者数据存放的地址进行对齐,后面会跟一个立即数。缺省表示 4 字节对齐。
;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
;用户栈和堆初始化,由 C 库函数_main 来完成
IF :DEF:__MICROLIB
;是否启用微库,
EXPORT __initial_sp ;=0x08000800
EXPORT __heap_base;=0x20000000
EXPORT __heap_limit;=0x20000000
ELSE ;如果没有使用微库 IMPORT __use_two_region_memory EXPORT __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 如 果没 有 定 义 __MICROLIB , 则 才 用 双 段 存 储 器 模 式 , 且 声 明 标 号__user_initial_stackheap 具有全局属性,让用户自己来初始化堆栈。
ALIGN
IF,ELSE,ENDIF:汇编的条件分支语句,跟 C 语言的 if ,else 类似
END:文件结束
ENDIF
END
内存映射的图像
这张图很重要,在后续都会用到,
main函数前的启动文件分析(一下的分析都要结合内存映射图像分析)
程序的编译会生成axf文件,和map的文件,如果希望生成汇编文件和bin文件需要使用命令行生成,
fromelf --text -c -o .ListingsLED.asm .ObjectsLED.axf
fromelf --bin -o .ListingsLED.bin .ObjectsLED.axf
代码见CSDN链接为:
编译环境为Keil5,
烧写的bin文件,烧写的区域为STM32F103ZET6内部的ROM
内部的ROM地址为0x08000000
LED.bin
Code 代表执行的代码,程序中所有的函数都位于此处。
RO-data 代表只读数据,程序中所定义的全局常量数据和字符串都位于此处
RW-data 代表已初始化的读写数据,程序中定义并且初始化的全局变量和静态变量位于此处。
ZI-data 代表未初始化的读写数据,程序中定义了但没有初始化的全局变量和静态变量位于此处。
ZI英语是zero initial,就是程序中用到的变量并且被系统初始化为0的变量的字节数,
keil编译器默认是把你没有初始化的变量都赋值一个0,这些变量在程序运行时是保存在RAM中的。
程序的大小为0x288字节,648字节
以上可以了解到,LED.bin文件是下载到STM32ZET6的0x08000000~0x08000280处,
map文件使用微库的映射
内存映射的图像
这里使用了Mircro LIB
CPU从Reset_Handler=0x0800017f处执行,MSP=0x2000400.
启动文件分析 startup_stm32f10x_hd.s
1、Stack-栈
Stack_Size EQU 0x00000800
;EQU 宏定义的未定义,相当于C中的define
AREA STACK, NOINIT, READWRITE, ALIGN=3
;AREA 告诉汇编器编译一个新的代码段或者数据段,STACK 表明段名,这个可以任意命名;
;NOINIT 表示不初始化,READWRITE 表示可读可写,ALIGN=3,表示8字节对齐
Stack_Mem SPACE Stack_Size
;SPACE 用于分配一定的内存空间,单位字节,指定大小为Stack_Size
__initial_sp
;__initial_sp 紧挨着SPACE语句放置,表示栈的结束地址,栈顶地址,栈由高向低生长,
__initial_sp=0x20000800
__initial_spTop EQU 0x20000400 ; stack used for SystemInit_ExtMemCtl
; always internal RAM used
;在0x20000400处的位置为__initial_spTop
;此段为名词为STACK段,大小为0x800
; Heap Configuration
; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
2、Heap-堆
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base
;__heap_base 表示堆的起始地址,,
Heap_Mem SPACE Heap_Size
__heap_limit
;__heap_limit 表示堆的结束地址,
;堆主要用来动态内存分配,像malloc()函数申请的内存就在堆上,
;以上的代码段名词为HEAP,大小为0
PRESERVE8
THUMB
;PERSERVE8 指定当前文件的堆栈按照8字节对齐
; THUMB表示后面指令兼容THUMB指令,
3、 向量表
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
;定义一个数据区(实则为startup_stm32f10x_hd.o 数据区名称为RESET(在内存映射的图像)),
;RESET可读,声明__Vectors,__Vectors_End和__Vectors_Size三个标号,三个标号具有全局属性,可以供外部文件调用,
EXPORT:声明一个标号可被外部文件使用,标号具有全局属性,如果是IAR编译器,则使用GLOBAL
当内核响应了一个发生的异常后,对应的异常服务例程(ESR)就会执行。为了决定 ESR的入口地址, 内核使用了―向量表查表机制‖。这里使用一张向量表。向量表其实是一个WORD(32 位整数)数组,每个下标对应一种异常,该下标元素的值则是该 ESR 的入口地址。向量表在地址空间中的位置是可以设置的,通过 NVIC 中的一个重定位寄存器来指出向量表的地址。在复位后,该寄存器的值为 0。因此,在地址 0 (即 FLASH 地址 0) 处必须包含一张向量表,用于初始时的异常分配。要注意的是这里有个另类: 0 号类型并不是什么入口地址,而是给出了复位后 MSP 的初值。
F103向量表
__Vectors DCD __initial_spTop ; Top of Stack ;栈顶地址0x200004000
;__Vectors 向量的其实地址,在STM32ZET6,__Vectors=0x08000000
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
;DCD:分配一个或者多个以字为单位的内存,以四字节对齐,并要求初始化这些内存。在向量表中, DCD 分配了一堆内存;
__Vectors_End
;__Vectors_End=0x0800012c
__Vectors_Size EQU __Vectors_End - __Vectors
;__Vectors_Size =0x0800012c-0x08000000=0x12c;
;以上的代码段名词为RESET,范围为0x08000000~0x0800012c,大小为0x00000130
AREA |.text|, CODE, READONLY
;同理上文可知text代码段 可读
; Dummy SystemInit_ExtMemCtl function
SystemInit_ExtMemCtl PROC
EXPORT SystemInit_ExtMemCtl [WEAK]
BX LR
ENDP
SystemInit_ExtMemCtl区域SystemInit_ExtMemCtl=0x0800017c
标记__weak 或 [weak]的函数 就是用在本文件占位的,如果别的文件重写的这个函数就用别文件的,否则使用本文件的。加上了 [WEAK] 修饰. 用户可以根据自己的需要重新编写自己的处理函数, 而且只要命名一样就 OK 了. ( WEAK:表示弱定义,如果外部文件优先定义了该标号则首先引用该标号,如果外部文件没有声明也不会出错。这里表示复位子程序可以由用户在其他文件重新实现,这里并不是唯一的。)
;利用PROC、ENDP这一对伪指令把程序段分为若干个部分
; Reset handler routine
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT:表示该标号来自外部文件,跟 C 语言中的 EXTERN 关键字类似。这里__main 这两个函数均来自外部的文件。
LDR R0, = SystemInit_ExtMemCtl ; initialize external memory controller
BLX R0
;BLX挑战到寄存器值得地址,并把跳转前的下一个指令的地址保存到lr寄存器中,
LDR R1, = __initial_sp ; restore original stack pointer
ldr;将存储器中加载字到一个寄存器中,
MSR MSP, R1
LDR R0, =__main ;
这里的__main和c文件的main是不同的地址,__main来自于编译器中
这里的__main=0x08000130
BX R0
;跳到寄存器值得地址,
ENDP
;这里存储的区域是编译器的__main,因为__main会条用外部的main,
__main区域 __main=0x08000130
…(因为__main会调用其他代码用…)
main.o区域
因为main条用了led.o
led.o区域 led=0x08000144
Stm32_Clock_Init.o区域 Stm32_Clock_Init=0x080001d0
; 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
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=0x0800019e
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 ALIGN:对指令或者数据存放的地址进行对齐,后面会跟一个立即数。缺省表示 4 字节对齐。
;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
;用户栈和堆初始化,由 C 库函数_main 来完成
IF :DEF:__MICROLIB
;是否启用微库,
EXPORT __initial_sp ;=0x08000800
EXPORT __heap_base;=0x20000000
EXPORT __heap_limit;=0x20000000
ELSE ;如果没有使用微库 IMPORT __use_two_region_memory EXPORT __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 如 果没 有 定 义 __MICROLIB , 则 才 用 双 段 存 储 器 模 式 , 且 声 明 标 号__user_initial_stackheap 具有全局属性,让用户自己来初始化堆栈。
ALIGN
IF,ELSE,ENDIF:汇编的条件分支语句,跟 C 语言的 if ,else 类似
END:文件结束
ENDIF
END
内存映射的图像
这张图很重要,在后续都会用到,
main函数前的启动文件分析(一下的分析都要结合内存映射图像分析)
程序的编译会生成axf文件,和map的文件,如果希望生成汇编文件和bin文件需要使用命令行生成,
fromelf --text -c -o .ListingsLED.asm .ObjectsLED.axf
fromelf --bin -o .ListingsLED.bin .ObjectsLED.axf
举报