STM32F10x的啟動匯編分析
;********************(C)COPYRIGHT2009STMicroelectronics********************
;*FileName:startup_stm32f10x_cl.s
;*Author:MCDApplicationTeam
;*Version:V3.1.0
;*Date:06/19/2009
;*Description:STM32F10xConnectivitylinedevicesvectortableforRVMDK
;*toolchain.
;*Thismoduleperforms:
;*-SettheinitialSP
;*-SettheinitialPC==Reset_Handler
;*-SetthevectortableentrieswiththeexceptionsISRaddress
;*-Branchesto__mainintheClibrary(whicheventually
;*callsmain()).
;*AfterResettheCortexM3processorisinThreadmode,
;*priorityisPrivileged,andtheStackissettoMain.
;*<<
;*******************************************************************************
;THEPRESENTFIRMWAREWHICHISFORGUIDANCEONLYAIMSATPROVIDINGCUSTOMERS
;WITHCODINGINFORMATIONREGARDINGTHEIRPRODUCTSINORDERFORTHEMTOSAVETIME.
;ASARESULT,STMICROELECTRONICSSHALLNOTBEHELDLIABLEFORANYDIRECT,
;INDIRECTORCONSEQUENTIALDAMAGESWITHRESPECTTOANYCLAIMSARISINGFROMTHE
;CONTENTOFSUCHFIRMWAREAND/ORTHEUSEMADEBYCUSTOMERSOFTHECODING
;INFORMATIONCONTAINEDHEREININCONNECTIONWITHTHEIRPRODUCTS.
;*******************************************************************************
;Amountofmemory(inbytes)allocatedforStack
;Tailorthisvaluetoyourapplicationneeds
;
;
;
;首先對棧和堆的大小進(jìn)行定義,并在代碼區(qū)的起始處建立中斷向量表,其第一個表項(xiàng)是棧
;頂?shù)刂?,第二個表項(xiàng)是復(fù)位中斷服務(wù)入口地址。然后在復(fù)位中斷服務(wù)程序中跳轉(zhuǎn)C/C++標(biāo)
;準(zhǔn)實(shí)時(shí)庫的__main函數(shù)。假設(shè)STM32被設(shè)置為從內(nèi)部FLASH啟動中斷向量表起始地位為0x8000000,
;則棧頂?shù)刂反娣庞?x8000000處,而復(fù)位中斷服務(wù)入口地址存放于0x8000004處。當(dāng)STM32遇
;到復(fù)位信號后,則從0x80000004處取出復(fù)位中斷服務(wù)入口地址繼而執(zhí)行復(fù)位中斷服務(wù)程序,
;然后跳轉(zhuǎn)__main函數(shù),最后來到C的世界。
;DCD指令:作用是開辟一段空間,其意義等價(jià)于C語言中的地址符“&”。開始建立的中斷向量
;表則類似于使用C語.其每一個成員都是一個函數(shù)指針,分別指向各個中斷服務(wù)函數(shù)
;偽指令A(yù)REA,表示開辟一段大小為Stack_Size的內(nèi)存空間作為棧,段名是STACK,可讀可寫。
;NOINIT:指定此數(shù)據(jù)段僅僅保留了內(nèi)存單元,而沒有將各初始值寫入內(nèi)存單元,或者將各個內(nèi)存單元值初始化為0
;常見的數(shù)據(jù)定義偽指令有如下幾種:
;—DCB用于分配一片連續(xù)的字節(jié)存儲單元并用指定的數(shù)據(jù)初始化。
;—DCW(DCWU)用于分配一片連續(xù)的半字存儲單元并用指定的數(shù)據(jù)初始化。
;—DCD(DCDU)用于分配一片連續(xù)的字存儲單元并用指定的數(shù)據(jù)初始化。
;—DCFD(DCFDU)用于為雙精度的浮點(diǎn)數(shù)分配一片連續(xù)的字存儲單元并用指定的數(shù)據(jù)初始化。
;—DCFSDCFSU)用于為單精度的浮點(diǎn)數(shù)分配一片連續(xù)的字存儲單元并用指定的數(shù)據(jù)初始化。
;—DCQDCQU)用于分配一片以8字節(jié)為單位的連續(xù)的存儲單元并用指定的數(shù)據(jù)初始化。
;—SPACE用于分配一片連續(xù)的存儲單元
;—MAP用于定義一個結(jié)構(gòu)化的內(nèi)存表首地址
;—FIELD用于定義一個結(jié)構(gòu)化的內(nèi)存表的數(shù)據(jù)域
;EXPORT偽指令用于在程序中聲明一個全局的標(biāo)號,該標(biāo)號可在其他的文件中引用。EXPORT可用GLOBAL代替。標(biāo)號在程序中區(qū)分大小寫,[WEAK]選項(xiàng)聲明其他的同名標(biāo)號優(yōu)先于該標(biāo)號被引用。
;;啟動代碼作用一般是:
;;1)堆和棧的初始化;
;2)向量表定義;
;;3)地址重映射及中斷向量表的轉(zhuǎn)移;
;;4)設(shè)置系統(tǒng)時(shí)鐘頻率;
;;5)中斷寄存器的初始化;
;;6)進(jìn)入C應(yīng)用程序。
;1)堆和棧的初始化
Stack_SizeEQU0x00000400 ;棧區(qū)(stack)—由編譯器自動分配釋放,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧
;SPACE用來分配一片連續(xù)的存儲區(qū)域并初始化為0.
AREASTACK,NOINIT,READWRITE,ALIGN=3;AREA偽指令用于定義一個代碼段或數(shù)據(jù),;定義棧,可初始為0,8字節(jié)對齊2*2*2,2的3次方
;NOINIT:指定此數(shù)據(jù)段僅僅保留了內(nèi)存單元,
;READWRITE屬性:指定本段為可讀可寫,數(shù)據(jù)段的默認(rèn)屬性為READWRITE。
;STACK段名
;ALIGN屬性:使用方式為ALIGN表達(dá)式。在默認(rèn)時(shí),ELF(可執(zhí)行連接文件)的代碼段和數(shù)據(jù)段是按字對齊的,表達(dá)式的取值范圍為0~31,相應(yīng)的對齊方式為2表達(dá)式次方。
Stack_MemSPACEStack_Size ;;分配0x400個連續(xù)字節(jié),并初始化為0
__initial_sp ;標(biāo)號__initial_sp,表示??臻g頂?shù)刂贰?;匯編代碼地址標(biāo)號
;
;
;
Heap_SizeEQU0x00000200 ;堆區(qū)(heap)—一般由程序員分配釋放,若程序員不釋放,程序結(jié)束時(shí)可能由OS回收。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表
AREAHEAP,NOINIT,READWRITE,ALIGN=3 ;ALIGN用來指定對齊方式,8字節(jié)對齊
__heap_base ;表示堆空間起始地址
Heap_MemSPACEHeap_Size
__heap_limit ;表示堆空間結(jié)束地址
PRESERVE8 ;PRESERVE8指令指定當(dāng)前文件保持堆棧八字節(jié)對齊
THUMB ;告訴匯編器下面是32位的Thumb指令,如果需要匯編器將插入位以保證對齊
;2)中斷向量表定義
;VectorTableMappedtoAddress0atReset ;實(shí)際上是在CODE區(qū)(假設(shè)STM32從FLASH啟動,則此中斷向量表起始地址即為0x8000000)
AREARESET,DATA,READONLY ;定義一塊數(shù)據(jù)段,只可讀,段名字是RESET
;DATA屬性:用于定義數(shù)據(jù)段,默認(rèn)為READWRITE。指定本段為可讀可寫
EXPORT__Vectors ;EXPORT:在程序中聲明一個全局的標(biāo)號__Vectors,該標(biāo)號可在其他的文件中引用
EXPORT__Vectors_End ;在程序中聲明一個全局的標(biāo)號__Vectors_End
EXPORT__Vectors_Size ;在程序中聲明一個全局的標(biāo)號__Vectors_Size
__VectorsDCD__initial_sp;TopofStack 第一個表項(xiàng)是棧頂?shù)刂?br/>;該處物理地址值即為__Vetors標(biāo)號所表示的值,
;該地址中存儲__initial_sp所表示的地址值,
;大小為一個字(32bit)
DCDReset_Handler;ResetHandler第二個表項(xiàng)是復(fù)位中斷服務(wù)入口地址
DCDNMI_Handler;NMIHandler 不可屏蔽中斷?
DCDHardFault_Handler;HardFaultHandler硬件錯誤處理
DCDMemManage_Handler;MPUFaultHandler存儲器錯誤處理
DCDBusFault_Handler;BusFaultHandler總線錯誤處理
DCDUsageFault_Handler;UsageFaultHandler 用法錯誤處理
DCD0;Reserved;這種形式就是保留地址,不給任何標(biāo)號分配
DCD0;Reserved
DCD0;Reserved
DCD0;Reserved
DCDSVC_Handler;SVCallHandler 執(zhí)行系統(tǒng)服務(wù)調(diào)用指令(SVC)引發(fā)的異常
DCDDebugMon_Handler;DebugMonitorHandler調(diào)試監(jiān)視器(斷點(diǎn),數(shù)據(jù)觀察點(diǎn),或者是外部調(diào)試請求
DCD0;Reserved
DCDPendSV_Handler;PendSVHandler 為系統(tǒng)設(shè)備而設(shè)的“可懸掛請求”(pendablerequest)
DCDSysTick_Handler;SysTickHandler 系統(tǒng)滴答定時(shí)器
;ExternalInterrupts 外設(shè)中斷
DCDWWDG_IRQHandler;WindowWatchdog 窗口看門狗
DCDPVD_IRQHandler;PVDthroughEXTILinedetect 電源電壓檢測(PVD)中斷
DCDTAMPER_IRQHandler;Tamper
DCDRTC_IRQHandler;RTC
DCDFLASH_IRQHandler;Flash
DCDRCC_IRQHandler;RCC
DCDEXTI0_IRQHandler;EXTILine0
DCDEXTI1_IRQHandler;EXTILine1
DCDEXTI2_IRQHandler;EXTILine2
DCDEXTI3_IRQHandler;EXTILine3
DCDEXTI4_IRQHandler;EXTILine4
DCDDMA1_Channel1_IRQHandler;DMA1Channel1
DCDDMA1_Channel2_IRQHandler;DMA1Channel2
DCDDMA1_Channel3_IRQHandler;DMA1Channel3
DCDDMA1_Channel4_IRQHandler;DMA1Channel4
DCDDMA1_Channel5_IRQHandler;DMA1Channel5
DCDDMA1_Channel6_IRQHandler;DMA1Channel6
DCDDMA1_Channel7_IRQHandler;DMA1Channel7
DCDADC1_2_IRQHandler;ADC1andADC2
DCDCAN1_TX_IRQHandler;CAN1TX
DCDCAN1_RX0_IRQHandler;CAN1RX0
DCDCAN1_RX1_IRQHandler;CAN1RX1
DCDCAN1_SCE_IRQHandler;CAN1SCE
DCDEXTI9_5_IRQHandler;EXTILine9..5
DCDTIM1_BRK_IRQHandler;TIM1Break
DCDTIM1_UP_IRQHandler;TIM1Update
DCDTIM1_TRG_COM_IRQHandler;TIM1TriggerandCommutation
DCDTIM1_CC_IRQHandler;TIM1CaptureCompare
DCDTIM2_IRQHandler;TIM2
DCDTIM3_IRQHandler;TIM3
DCDTIM4_IRQHandler;TIM4
DCDI2C1_EV_IRQHandler;I2C1Event
DCDI2C1_ER_IRQHandler;I2C1Error
DCDI2C2_EV_IRQHandler;I2C2Event
DCDI2C2_ER_IRQHandler;I2C1Error
DCDSPI1_IRQHandler;SPI1
DCDSPI2_IRQHandler;SPI2
DCDUSART1_IRQHandler;USART1
DCDUSART2_IRQHandler;USART2
DCDUSART3_IRQHandler;USART3
DCDEXTI15_10_IRQHandler;EXTILine15..10
DCDRTCAlarm_IRQHandler;RTCalarmthroughEXTIline
DCDOTG_FS_WKUP_IRQHandler;USBOTGFSWakeupthroughEXTIline
DCD0;Reserved
DCD0;Reserved
DCD0;Reserved
DCD0;Reserved
DCD0;Reserved
DCD0;Reserved
DCD0;Reserved
DCDTIM5_IRQHandler;TIM5
DCDSPI3_IRQHandler;SPI3
DCDUART4_IRQHandler;UART4
DCDUART5_IRQHandler;UART5
DCDTIM6_IRQHandler;TIM6
DCDTIM7_IRQHandler;TIM7
DCDDMA2_Channel1_IRQHandler;DMA2Channel1
DCDDMA2_Channel2_IRQHandler;DMA2Channel2
DCDDMA2_Channel3_IRQHandler;DMA2Channel3
DCDDMA2_Channel4_IRQHandler;DMA2Channel4
DCDDMA2_Channel5_IRQHandler;DMA2Channel5
DCDETH_IRQHandler;Ethernet
DCDETH_WKUP_IRQHandler;EthernetWakeupthroughEXTIline
DCDCAN2_TX_IRQHandler;CAN2TX
DCDCAN2_RX0_IRQHandler;CAN2RX0
DCDCAN2_RX1_IRQHandler;CAN2RX1
DCDCAN2_SCE_IRQHandler;CAN2SCE
DCDOTG_FS_IRQHandler;USBOTGFS
__Vectors_End ;結(jié)束
__Vectors_SizeEQU__Vectors_End-__Vectors;得到向量表的大小,304個字節(jié)也就是0x130個字節(jié)
;3)地址重映射及中斷向量表的轉(zhuǎn)移;
AREA|.text|,CODE,READONLY ;定義一個代碼段,可讀,段名字是.text段名若以數(shù)字開頭,則該段名需用"|"括起來,如|1_test|。
;定義只讀數(shù)據(jù)段,實(shí)際上是在CODE區(qū),如果在FLASH區(qū)起動,則中斷向量起始地址為0X8000000
;;CODE屬性:用于定義代碼段,默認(rèn)為READONLY
;Resethandlerroutine
Reset_HandlerPROC ;;標(biāo)記一個函數(shù)的開始;利用PROC、ENDP這一對偽指令把程序段分為若干個過程,使程序的結(jié)構(gòu)加清晰
EXPORTReset_Handler[WEAK];在外部沒有定義該符號時(shí)導(dǎo)出該符號Reset_Handler
;EXPORT偽指令用于在程序中聲明一個全局的標(biāo)號
IMPORT__main;IMPORT:偽指令用于通知編譯器要使用的標(biāo)號在其他的源文件中定義
LDRR0,=__main ;__main為運(yùn)行時(shí)庫提供的函數(shù);完成堆棧,堆的初始化等工作,會調(diào)用下面定義的__user_initial_stackheap
BXR0 ;跳到__main,進(jìn)入C的世界
ENDP
;DummyExceptionHandlers(infiniteloopswhichcanbemodified)
;虛擬異常處理器(無限循環(huán)可以修改了)
NMI_HandlerPROC ;PROC表示匯編函數(shù)的開始
EXPORTNMI_Handler[WEAK];WEAK聲明其他的同名標(biāo)號優(yōu)先于該標(biāo)號被引用,就是說如果外面聲明了的話,
B. ;會調(diào)用外面的
ENDP
HardFault_Handler
PROC ;PROC表示匯編函數(shù)的開始
EXPORTHardFault_Handler[WEAK];換行的意思
B.
ENDP
MemManage_Handler
PROC ;PROC表示匯編函數(shù)的開始
EXPORTMemManage_Handler[WEAK]
B.
ENDP
BusFault_Handler
PROC ;PROC表示匯編函數(shù)的開始
EXPORTBusFault_Handler[WEAK]
B.
ENDP
UsageFault_Handler
PROC
EXPORTUsageFault_Handler[WEAK]
B.
ENDP
SVC_HandlerPROC ;PROC表示匯編函數(shù)的開始
EXPORTSVC_Handler[WEAK]
B.
ENDP
DebugMon_Handler
PROC ;PROC表示匯編函數(shù)的開始
EXPORTDebugMon_Handler[WEAK]
B.
ENDP
PendSV_HandlerPROC
EXPORTPendSV_Handler[WEAK]
B.
ENDP
SysTick_HandlerPROC ;PROC表示匯編函數(shù)的開始
EXPORTSysTick_Handler[WEAK]
B.
ENDP
Default_HandlerPROC
EXPORTWWDG_IRQHandler[WEAK]
EXPORTPVD_IRQHandler[WEAK]
EXPORTTAMPER_IRQHandler[WEAK]
EXPORTRTC_IRQHandler[WEAK]
EXPORTFLASH_IRQHandler[WEAK]
EXPORTRCC_IRQHandler[WEAK]
EXPORTEXTI0_IRQHandler[WEAK]
EXPORTEXTI1_IRQHandler[WEAK]
EXPORTEXTI2_IRQHandler[WEAK]
EXPORTEXTI3_IRQHandler[WEAK]
EXPORTEXTI4_IRQHandler[WEAK]
EXPORTDMA1_Channel1_IRQHandler[WEAK]
EXPORTDMA1_Channel2_IRQHandler[WEAK]
EXPORTDMA1_Channel3_IRQHandler[WEAK]
EXPORTDMA1_Channel4_IRQHandler[WEAK]
EXPORTDMA1_Channel5_IRQHandler[WEAK]
EXPORTDMA1_Channel6_IRQHandler[WEAK]
EXPORTDMA1_Channel7_IRQHandler[WEAK]
EXPORTADC1_2_IRQHandler[WEAK]
EXPORTCAN1_TX_IRQHandler[WEAK]
EXPORTCAN1_RX0_IRQHandler[WEAK]
EXPORTCAN1_RX1_IRQHandler[WEAK]
EXPORTCAN1_SCE_IRQHandler[WEAK]
EXPORTEXTI9_5_IRQHandler[WEAK]
EXPORTTIM1_BRK_IRQHandler[WEAK]
EXPORTTIM1_UP_IRQHandler[WEAK]
EXPORTTIM1_TRG_COM_IRQHandler[WEAK]
EXPORTTIM1_CC_IRQHandler[WEAK]
EXPORTTIM2_IRQHandler[WEAK]
EXPORTTIM3_IRQHandler[WEAK]
EXPORTTIM4_IRQHandler[WEAK]
EXPORTI2C1_EV_IRQHandler[WEAK]
EXPORTI2C1_ER_IRQHandler[WEAK]
EXPORTI2C2_EV_IRQHandler[WEAK]
EXPORTI2C2_ER_IRQHandler[WEAK]
EXPORTSPI1_IRQHandler[WEAK]
EXPORTSPI2_IRQHandler[WEAK]
EXPORTUSART1_IRQHandler[WEAK]
EXPORTUSART2_IRQHandler[WEAK]
EXPORTUSART3_IRQHandler[WEAK]
EXPORTEXTI15_10_IRQHandler[WEAK]
EXPORTRTCAlarm_IRQHandler[WEAK]
EXPORTOTG_FS_WKUP_IRQHandler[WEAK]
EXPORTTIM5_IRQHandler[WEAK]
EXPORTSPI3_IRQHandler[WEAK]
EXPORTUART4_IRQHandler[WEAK]
EXPORTUART5_IRQHandler[WEAK]
EXPORTTIM6_IRQHandler[WEAK]
EXPORTTIM7_IRQHandler[WEAK]
EXPORTDMA2_Channel1_IRQHandler[WEAK]
EXPORTDMA2_Channel2_IRQHandler[WEAK]
EXPORTDMA2_Channel3_IRQHandler[WEAK]
EXPORTDMA2_Channel4_IRQHandler[WEAK]
EXPORTDMA2_Channel5_IRQHandler[WEAK]
EXPORTETH_IRQHandler[WEAK]
EXPORTETH_WKUP_IRQHandler[WEAK]
EXPORTCAN2_TX_IRQHandler[WEAK]
EXPORTCAN2_RX0_IRQHandler[WEAK]
EXPORTCAN2_RX1_IRQHandler[WEAK]
EXPORTCAN2_SCE_IRQHandler[WEAK]
EXPORTOTG_FS_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
CAN1_TX_IRQHandler
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
OTG_FS_WKUP_IRQHandler
TIM5_IRQHandler
SPI3_IRQHandler
UART4_IRQHandler
UART5_IRQHandler
TIM6_IRQHandler
TIM7_IRQHandler
DMA2_Channel1_IRQHandler
DMA2_Channel2_IRQHandler
DMA2_Channel3_IRQHandler
DMA2_Channel4_IRQHandler
DMA2_Channel5_IRQHandler
ETH_IRQHandler
ETH_WKUP_IRQHandler
CAN2_TX_IRQHandler
CAN2_RX0_IRQHandler
CAN2_RX1_IRQHandler
CAN2_SCE_IRQHandler
OTG_FS_IRQHandler
B.
ENDP
ALIGN
;*******************************************************************************
;UserStackandHeapinitialization(4)堆和棧的初始化
;*******************************************************************************
IF:DEF:__MICROLIB ;判斷是否使用DEF:__MICROLIB(microlib)
EXPORT__initial_sp ;使用的話則將棧頂?shù)刂罚咽寄┑刂焚x予全局屬
EXPORT__heap_base ;使外部程序可以使用
EXPORT__heap_limit
ELSE ;如果使用默認(rèn)C庫運(yùn)行時(shí)
IMPORT__use_two_region_memory ;定義全局標(biāo)號__use_two_region_memory
EXPORT__user_initial_stackheap ;聲明全局標(biāo)號__user_initial_stackheap,這樣外程序也可調(diào)用此標(biāo)號
;則進(jìn)行堆棧和堆的賦值,在__main函數(shù)執(zhí)行過程中調(diào)用
__user_initial_stackheap ;標(biāo)號__user_initial_stackheap,表示用戶堆棧初始化程序入口
LDRR0,=Heap_Mem ;保存堆始地址
LDRR1,=(Stack_Mem+Stack_Size) ;保存棧的大小
LDRR2,=(Heap_Mem+Heap_Size) ;保存堆的大小
LDRR3,=Stack_Mem ;保存棧頂指針
BXLR
ALIGN ;ALIGN屬性:使用方式為ALIGN表達(dá)式。在默認(rèn)時(shí),ELF(可執(zhí)行連接文件)的代碼段和數(shù)據(jù)段是按字對齊的,表達(dá)式的取值范圍為0~31,相應(yīng)的對齊方式為2表達(dá)式次方
ENDIF
END
;*******************(C)COPYRIGHT2009STMicroelectronics*****ENDOFFILE*****