This is the 9th day of my participation in Gwen Challenge

The source of the startup file is as follows:

; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

;栈初始化
Stack_Size      EQU     0x00000400   						;EQU定义栈空间的大小 1024字节,栈空间由编译器自动分配变量所占内存,该汇编语句等效于#define Stack_Size 0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3 	;定义一个名为STACK的内存单元,它是可读写的,对齐方式为2^3=8字节对齐
Stack_Mem       SPACE   Stack_Size   						;SPACE分配连续的栈存储空间,大小为0x00000400(1K),把首地址赋给Stack_Mem
__initial_sp     											;初始化堆栈指针,指向堆栈顶。
                                                  
; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

;堆初始化
Heap_Size       EQU     0x00000200   						;EQU定义堆空间的大小,堆空间由人为手动分配变量所占内存,该汇编语句等效于#define Heap_Size 0x00000200

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3  	;定义一个名为HEAP的内存单元,它是可读写的,对齐方式为2^3=8字节对齐
__heap_base								 					;堆起始地址 
Heap_Mem        SPACE   Heap_Size							;SPACE分配连续的堆存储空间,大小为0x00000200(512Bytes),把首地址赋给Heap_Mem
__heap_limit							  					;堆终止地址,与__heap_base配合限制堆的大小 

                PRESERVE8					   				;告诉编译器以8字节对齐,命令指定当前文件保持栈的八字节对齐
                THUMB					  					;告诉编译器使用THUMB指令集,THUMB 必须位于使用新语法的任何Thumb代码之前;定义复位段(中断向量表),并初始化

;中断向量表定义
; Vector Table Mapped to Address 0 at Reset					;中断向量表默认从地址0开始,如果使用了向量表重定位,则从重定位地址开始。假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000。
                AREA    RESET, DATA, READONLY				;定义一个名为RESET的数据段,它是只读类型的。
                EXPORT  __Vectors							;声明全局变量_Vectors,该标号可在其他文件中使用,表示中断向量表入口地址
                EXPORT  __Vectors_End						;向量表终止地址
                EXPORT  __Vectors_Size						;向量表空间大小


__Vectors       DCD     __initial_sp               ; Top of Stack  Top of Stack 第一个表项是栈顶地址;该处物理地址值即为 __Vetors 标号所表示的值;该地址中存储__initial_sp所表示的地址值,
;大小为一个字(32bit) 
                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  	总线错误中断,一般发生在数据访问异常,比如fsmc访问不当
                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  		挂起异常,此处可以用作RTOS的上下文切换异常,这是被推荐使用的,因为Cortex-M4会在异常发生时自动保存R0-R3,R12,R13(堆栈指针SP),R14(链接地址,也叫返回地址LR,在异常返回时使用),R15(程序计数器PC,为当前应用程序+4)和中断完成时自动恢复,我们只需保存R4-R11,大大减少了中断响应和上下文切换的时间。
                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_Size  EQU  __Vectors_End - __Vectors		 		;得到向量表的大小 共76个中断向量,304个字节也就是0x130个字节

;地址重映射及中断向量表的转移 
               AREA    |.text|, CODE, READONLY    			;定义一个代码段,可读,段名字是.text  段名若以数字开头,则该段名需用"|"括起来,如|1_test|。 |.text|  表示由 C 编译程序产生的代码段,或用于以某种方式与 C 库关联的代码段。			
															;定义只读数据段,实际上是在CODE区,如果在FLASH区起动,则 中断向量起始地址为0X8000000

;复位向量处理函数
; Reset handler
Reset_Handler   PROC						 				;标记一个函数的开始;利用PROC、ENDP这一对伪指令把程序段分为若干个过程,使程序的结构加清晰
                EXPORT  Reset_Handler             [WEAK]    ;此处[WEAK]表示弱定义,优先执行其他文件的定义
                IMPORT  __main								;伪指令用于通知编译器要使用的标号在其他的源文件中定义
                IMPORT  SystemInit
                LDR     R0, =SystemInit						; 装载寄存器指令
                BLX     R0        				      		; 带链接的跳转,切换指令集。将处理器的工作状态由ARM状态切换到Thumb状态,该指令同时将PC的当前内容保存到寄存器R14中。因此,当子程序使用Thumb指令集,而调用者使用ARM指令集时,可以通过BLX指令实现子程序的调用和处理器工作状态的切换。同时,子程序的返回可以通过将寄存器R14值复制到PC中来完成。         
                LDR     R0, =__main					  		; 切换指令集,main函数不返回
                BX      R0									;BX指令跳转到指令中所指定的目标地址,目标地址处的指令既可以是ARM指令,也可以是Thumb指令。
                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       .									; 点“.”,它表示跳转到当前的指令地址处(即当前的 PC 值),也就是进入到当前的死循环中了。
                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					 					; 默认是字对齐方式,也说明了代码是4字节对齐的		

;*******************************************************************************
; User Stack and Heap initialization      用户堆栈初始化
;*******************************************************************************
                 IF      :DEF:__MICROLIB       				;判断是否使用DEF:__MICROLIB(micro lib)在keil中选中 option--target--USE MicroLIB
                
                 EXPORT  __initial_sp		  				;使用的话则将栈顶地址,堆始末地址赋予全局属性使外部程序可以使用
                 EXPORT  __heap_base            			
                 EXPORT  __heap_limit
                
                 ELSE							  			;如果使用默认C库运行时
                
                 IMPORT  __use_two_region_memory   			;定义全局标号__use_two_region_memory
                 EXPORT  __user_initial_stackheap    		;声明全局标号__user_initial_stackheap,这样外部程序也可调用此标号,进行堆栈和堆的赋值,在__main函数执行过程中调用
                 
__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									;LR连接寄存器,也就是R14,用于函数或者子程序调用返回地址的保存。 等同于 mov  pc,lr 即跳转到lr中存放的地址处

                 ALIGN										;设置对齐方式,在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐

                 ENDIF

                 END

;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE*****
Copy the code

Let’s start with a line-by-line analysis of the key code

Stack initialization:

To understand these three lines of code, first understand the meaning of these assembly instructions

1, the EQU

EQU defines the size of the stack space, which is automatically allocated by the compiler to memory occupied by variables. This assembly statement is equivalent to #define Stack_Size 0x00000400. This is where the stack size is first defined as 0x400, or 1024 bytes.

2, the AREA

So the second line defines a memory cell called STACK, which is read-write and aligned with 2^3=8 bytes

3, SPACE

The third line of code means that I’m going to initialize my STACK to zero.

The last line of __initial_sp means to initialize the stack pointer and point to the top of the stack.

Heap initialization:

1. EQU defines the size of the heap space (512 bytes). The heap space is allocated manually by variables

Define a memory unit called HEAP, which is read-write and aligned to 2^3=8 bytes

3. Set the start heap address

4, SPACE allocate contiguous heap storage SPACE 0x00000200(512Bytes) and assign the first address to Heap_Mem

5, the end of the heap address, in conjunction with __heap_base to limit the size of the heap

6. Tells the compiler to align the file with 8 bytes, and specifies that the current file keeps the stack aligned with 8 bytes

7, tell the compiler that the following code starts using the THUMB instruction set and that THUMB must precede any THUMB code using the new syntax. Define the reset segment (interrupt vector table) and initialize it.

Interrupt direction scale definition:

By default, the interrupt routing table starts at address 0. If routing table relocation is used, the relocation address starts. If STM32 is started from FLASH, the start address of the interrupt direction table is 0x8000000.

1. Define a data segment named RESET that is read-only.

2. Declare the global variable _Vectors, which can be used in other files to indicate the entry address of the interrupt vector table

3. End address of the vector table

4. Space size of vector scale

Interrupt vector table entry address:

The first entry is the address at the Top of the Stack. The physical address value is the value represented by the __Vetors label. This address stores the address value represented by __initial_sp.

Assign addresses to each interrupt vector in turn, and the assigned addresses are as follows:

__Vectors_End indicates the end of the vector table.

Address remapping and interrupt transfer to table:

Define a code, can read, name is. The text if section name begin with Numbers, is the segment name must be enclosed “|”, such as | 1 _test |. |. Text | said the code generated by the C compiler, or used in some way associated with C library of code. Define the read-only data segment, which is actually in the CODE area. If started in the FLASH area, the interrupt vector starts at address 0X8000000.

Reset vector processing functions:

The use of PROC, ENDP this pair of pseudo-instructions to segment the program, equivalent to the C language {} role.

If the Reset_Handler function is defined in the program, the user-defined Reset_Handler function will be executed. If the user does not define the Reset_Handler function, the user-defined Reset_Handler function will be executed. If the user does not define the Reset_Handler function, the user-defined Reset_Handler function will be executed. Execute the current function. Weak definition means that when two functions have the same name, the user-defined function is executed first.

This is to prevent the user to enable the interrupt without interrupting the service function, resulting in a program crash. If interrupts are enabled and the user does not define the interrupt service function, the default interrupt is entered, and the default interrupt is an infinite loop.

Use IMPORT to declare the main() and SystemInit() functions.

Using the LDR command, load the address of the function SystemInit into register R0.

Jump to the SystemInit() function with the BLX instruction.

Next, load the main() address with the LDR instruction.

Jump to main() with the BX instruction.

Imaginary exception handlers:

Output abnormal direction table label:

Weak definitions are also used here; if external definitions are defined, the external definitions take precedence, otherwise the following function definitions are executed.

Implement weakly defined functions:

Implementation of each interrupt function, but here the interrupt function is empty function, no specific implementation, the user needs to achieve in the code.

User stack initialization:

Use if and else to determine whether the microlibrary was selected

If the USE MicroLIB option is selected in keil, the if statement is executed, otherwise the else statement is executed, using the default C library.

IF :DEF:__MICROLIB ; DEF:__MICROLIB (micro lib) select option--target--USE MicroLIB EXPORT __initial_sp; If used, give global attributes to the top of the stack and the start and end of the heap so that external programs can use EXPORT __heap_base EXPORT __heap_limit ELSE; If you use the default C library runtime IMPORT __use_two_region_memory; Define the global label __use_two_region_memory EXPORT __user_initial_stackheap; Declare the global label __user_initial_stackheap so that external programs can also call this label, perform stack and heap assignments, and call __user_initial_stackheap during execution of the __main function; The label __user_initial_stackheap, representing the user stack initializer entry LDR R0, = Heap_Mem; Save heap start address LDR R1, =(Stack_Mem + Stack_Size); LDR R2, = (Heap_Mem + Heap_Size); Save heap size LDR R3, = Stack_Mem; Save the top pointer to the stack BX LR; The LR connection register, also known as R14, is used to save the return address of a function or subroutine call. Equivalent to mov PC, LR jumps to the address stored in LR  ALIGN; Set the alignment. By default, ELF (Executable connection file) code segments and data segments are word-aligned to ENDIFCopy the code