Keil5-STM32F103ZET6-案列一1.LED点灯

本工程代码下载区:
https://download.csdn.net/download/qq_25140013/11985712

在这里插入图片描述

代码见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 .\Listings\LED.asm .\Objects\LED.axf
fromelf --bin -o .\Listings\LED.bin .\Objects\LED.axf
在这里插入图片描述
在这里插入图片描述

   1、         

LDR R0, = SystemInit_ExtMemCtl ; initialize external memory controller SystemInit_ExtMemCtl =0x0800017c,由于SystemInit_ExtMemCtl 并没有任何代码,直接返回就行,有人问为什么要加这一段,其实可以不加,该段为了初始化外部存储器控制器,只预留了一个接口而已,不必太在意,
BLX R0
2、
LDR R1, = __initial_sp ; restore original stack pointer
__initial_sp =0x20000800
MSR MSP, R1
将0x20000800值赋给MSP(主堆栈指针),主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程);堆栈指针的最低两位永远是 0,这意味着堆栈总是 4 字节对齐的
在这里插入图片描述
;这汇编就是将0x20000800赋值给MSP寄存器
这里打断一下介绍一下一些寄存器

在这里插入图片描述
在这里插入图片描述
这里就详细介绍,我们还是接着分析我们的启动代码
3、 LDR R0, =__main =0x08000130
BX R0

在这里插入图片描述

程序跳到了__main处 sp保存0x20000800,
BL跳转到__scatterload处,0x80001ac,带返回值的挑战,lr保存的是0x08000138
在这里插入图片描述
LDR r4,[pc,#24] ; [0x80001c8] = 0x8000278
LDR r5,[pc,#28] ; [0x80001cc] = 0x8000288
分析这段汇编前,先不急的去分析他的逻辑,先分析0x8000278 和0x8000288是什么,在内存映射图像中的区域为Region$$Table
在这里插入图片描述
分析汇编这段的汇编肯定更内存映射区域的内容有关
在这里插入图片描述
在这里插入图片描述

这段的汇编功能是:
r4=0x8000278 r5=0x8000288,比较r4和r5,
如果不相等,r0=[0x8000278 +0xc]=[0x8000284 ]=0x08000268,r3=0x08000269,r0=0x08000288;
r1=0x20000000;r2=0x00000800,然后跳转到r3=0x08000269位置上执行,
在这里插入图片描述

这里汇编代码,在分析这段代码前,我们可以知道代码的返回为lr=0x080001be;
这段代码的功能是;
r0=0x0,比较r2=0x800不等于0;如果不等,将r0的内容存储在r1=0x20000000处,并且r1=r1+0x4;
r2=0x800-0x02=0x7FC,然后比较r2=0x7FC是否等于零,这就形成了一个循环,这里直接跳到最好一次执行循环,r1=0x20008000,r2=0x0,比较r2=0x0等于0,执行BX 0x080001BE,
(分析可知,这段的循环功能是把0x20000000到0x20000800内存清空,)
在这里插入图片描述
以上分析程序跳到了0x080001BE处,
在这里插入图片描述
这段汇编的功能,r4=0x8000278+0x10=0x8000288 ,r5=0x8000288 ,BL=0x8000138;

在这里插入图片描述
然后跳转到0x8000169处,
在这里插入图片描述
这就跳到了main函数的位置,
经过仔细的分析,终于运行到了我们熟悉的main位置,该工程使用keil5,采用硬件仿真器,开发板为STM32F103ZET6板,

这里总结启动文件,

1、启动文件调用__main文件
在这里插入图片描述
2、_main调用__scatterload
在这里插入图片描述
__scatterload其中调用了__scatterload_zeroinit 来清空内存区域0x20000000到0x20000800
在这里插入图片描述
3、__scatterload调用了_main_init
在这里插入图片描述

4、_main_init调用了main
在这里插入图片描述
到此main函数前的启动分析以及结束,

汇编代码点亮LED

本文的目的不仅仅是为了分析启动代码,而是为了点灯,当然点灯是一件很容易的事情,为了巩固一下汇编能力,点灯采用汇编文件的代码形式。纯粹为了多了解一下汇编,没有任何的其他想法,后续的驱动分析,能使用汇编,尽量用汇编来编写代码。
在这里插入图片描述
点亮LED0 属于PB5引脚,基地址为0x40010C00

在这里插入图片描述
在这里插入图片描述
寄存器的配置
在这里插入图片描述
在这里插入图片描述

根据以上的寄存器很快的就可以写出一点灯的汇编代码了
在这里插入图片描述
这里采用的c文件的嵌套汇编的写法,
另外还需要配置系统的时钟系统,由于时钟系统采用汇编写,我估计会把我搞晕,我相信也会把大家搞晕,这里就使用C来写了,我们可以通过汇编来调试整个程序。

在这里插入图片描述
上图的汇编程序,先初始化时钟,里面使用到的寄存器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里不懂的按照STM32中文参考手册进行配置,具体的功能就不进行介绍了,

程序最后运行都了这里
在这里插入图片描述
这里的灯也点亮了,
在这里插入图片描述
到这里本文的已经结束了。欢迎指正本文的错误,
本博客的所有工程下载链接,
https://download.csdn.net/download/qq_25140013/11985712

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值