title: ARM Assembly FPU Interrupt Handler - STM32L4
body: <p>I'm trying to implement floating point operations on my STM32L476 Discovery Board, ARM Cortex-M4 CPU. All of my code is to be written only in ARM Assembly only.</p>
  
  <p>First, I enabled the FPU by activating the CoProcesser 10 and 11 by,</p>
  
  <pre><code>.thumb
  .thumb_func
  .globl fpu_init
  fpu_init:
      ldr r0,=0xE000ED88
      ldr r1,[r0]
      ldr r2,=0xF00000
      orr r1,r2, #(0xF &lt;&lt; 20)
      str r1,[r0]
      dsb
      isb
      bx lr
  
  </code></pre>
  
  <p>This is the rest of the program, where I implement floating point operations.</p>
  
  <pre><code>.syntax unified
  .global main
  .fpu vfpv4
  
  .type main, %function
  main:
    bl fpu_init
    LDR R0, =val1           @ load variable address
    VLDR S0, [R0]           @ load the value into the VFP register
  
    LDR R0, =val2           @ load variable address
    VLDR S1, [R0]           @ load the value into the VFP register
  
    VMUL.F32 S2, S0, S1     @ compute S2 = S0 * S1
  
    VCVT.F64.F32 D4, S2     @ covert the result to double precision for printing
    VMOV R1, R2, D4         @ split the double VFP register into two ARM registers
    BL  _printf_result      @ print the result
  
    B   _exit               @ branch to exit procedure with no return
    .size main, .-main
  
  _exit:  
    MOV R7, #4              @ write syscall, 4
    MOV R0, #1              @ output stream to monitor, 1
    MOV R2, #21             @ print string length
    LDR R1, =exit_str       @ string at label exit_str:
    SWI 0                   @ execute syscall
    MOV R7, #1              @ terminate syscall, 1
    SWI 0                   @ execute syscall
  
  _printf_result:
    PUSH {LR}               @ push LR to stack
    LDR R0, =result_str     @ R0 contains formatted string address
    BL printf               @ call printf
    POP {PC}                @ pop LR from stack and return
  
  .data
  result_str:     .asciz      "Multiplication result = %f \n"
  exit_str:       .ascii      "Terminating program.\n"
  val1:           .float      3.14159
  val2:           .float      0.100
  </code></pre>
  
  <p>Both the above code are in my main.s.</p>
  
  <p>The problem arises when, my program reaches the first VLDR function, and jumps to default handler in <code>startup_stm32l476xx.s</code> file (My guess is the floating point operation function is undefined).</p>
  
  <p>In my <code>startup_stm32l476xx.s</code> the <code>FPU_IRQHandler</code> mapped to <code>Default_Handler</code>.</p>
  
  <pre><code>    .weak   FPU_IRQHandler
      .thumb_set FPU_IRQHandler,Default_Handler
  </code></pre>
  
  <p>Is the VLDR being jumped to <code>Default_Handler</code>, because it is undefined, or because I haven't written a <code>FPU_IRQHandler</code> in my program.</p>
  
  <p>How do I write a <code>FPU_IRQHandler</code> only in ARM Assembly without any additional C code.</p>
  
  <p>Additional Note: The file <code>startup_stm32l476xx.s</code> has <code>.fpu</code> set as <code>softvfp</code>. Will this cause a problem, even if I had set <code>.fpu vpfv4</code> in my <code>main.s</code></p>
  
  <pre><code>  .syntax unified
      .cpu cortex-m4
      .fpu softvfp
      .thumb
  </code></pre>
  
  <p>I'm pretty new to assembly, any help would be highly appreciated. Thanks</p>
  
  <p><strong>Edit: I've added my startup code. I am using PlatfromIO to build this project.</strong></p>
  
  <p>StartUP Code as Follows:</p>
  
  <pre><code>/**
    ******************************************************************************
    * @file      startup_stm32l476xx.s
    * @author    MCD Application Team
    * @brief     STM32L476xx devices vector table GCC toolchain.
    *            This module performs:
    *                - Set the initial SP
    *                - Set the initial PC == Reset_Handler,
    *                - Set the vector table entries with the exceptions ISR address,
    *                - Configure the clock system  
    *                - Branches to main in the C library (which eventually
    *                  calls main()).
    *            After Reset the Cortex-M4 processor is in Thread mode,
    *            priority is Privileged, and the Stack is set to Main.
    ******************************************************************************
    * @attention
    *
    * &lt;h2&gt;&lt;center&gt;&amp;copy; COPYRIGHT(c) 2017 STMicroelectronics&lt;/center&gt;&lt;/h2&gt;
    *
    * Redistribution and use in source and binary forms, with or without modification,
    * are permitted provided that the following conditions are met:
    *   1. Redistributions of source code must retain the above copyright notice,
    *      this list of conditions and the following disclaimer.
    *   2. Redistributions in binary form must reproduce the above copyright notice,
    *      this list of conditions and the following disclaimer in the documentation
    *      and/or other materials provided with the distribution.
    *   3. Neither the name of STMicroelectronics nor the names of its contributors
    *      may be used to endorse or promote products derived from this software
    *      without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    ******************************************************************************
    */
  
    .syntax unified
      .cpu cortex-m4
      .fpu softvfp
      .thumb
  
  .global g_pfnVectors
  .global Default_Handler
  
  /* start address for the initialization values of the .data section.
  defined in linker script */
  .word   _sidata
  /* start address for the .data section. defined in linker script */
  .word   _sdata
  /* end address for the .data section. defined in linker script */
  .word   _edata
  /* start address for the .bss section. defined in linker script */
  .word   _sbss
  /* end address for the .bss section. defined in linker script */
  .word   _ebss
  
  .equ  BootRAM,        0xF1E0F85F
  /**
   * @brief  This is the code that gets called when the processor first
   *          starts execution following a reset event. Only the absolutely
   *          necessary set is performed, after which the application
   *          supplied main() routine is called.
   * @param  None
   * @retval : None
  */
  
      .section    .text.Reset_Handler
      .weak   Reset_Handler
      .type   Reset_Handler, %function
  Reset_Handler:
    ldr   sp, =_estack    /* Atollic update: set stack pointer */
  
  /* Copy the data segment initializers from flash to SRAM */
    movs  r1, #0
    b LoopCopyDataInit
  
  CopyDataInit:
      ldr r3, =_sidata
      ldr r3, [r3, r1]
      str r3, [r0, r1]
      adds    r1, r1, #4
  
  LoopCopyDataInit:
      ldr r0, =_sdata
      ldr r3, =_edata
      adds    r2, r0, r1
      cmp r2, r3
      bcc CopyDataInit
      ldr r2, =_sbss
      b   LoopFillZerobss
  /* Zero fill the bss segment. */
  FillZerobss:
      movs    r3, #0
      str r3, [r2], #4
  
  LoopFillZerobss:
      ldr r3, = _ebss
      cmp r2, r3
      bcc FillZerobss
  
  /* Call the clock system intitialization function.*/
      bl  SystemInit
  /* Call static constructors */
      bl __libc_init_array
  /* Call the application's entry point.*/
      bl  main
  
  LoopForever:
      b LoopForever
  
  .size   Reset_Handler, .-Reset_Handler
  
  /**
   * @brief  This is the code that gets called when the processor receives an
   *         unexpected interrupt.  This simply enters an infinite loop, preserving
   *         the system state for examination by a debugger.
   *
   * @param  None
   * @retval : None
  */
      .section    .text.Default_Handler,"ax",%progbits
  Default_Handler:
  Infinite_Loop:
      b   Infinite_Loop
      .size   Default_Handler, .-Default_Handler
  /******************************************************************************
  *
  * The minimal vector table for a Cortex-M4.  Note that the proper constructs
  * must be placed on this to ensure that it ends up at physical address
  * 0x0000.0000.
  *
  ******************************************************************************/
      .section    .isr_vector,"a",%progbits
      .type   g_pfnVectors, %object
      .size   g_pfnVectors, .-g_pfnVectors
  
  
  g_pfnVectors:
      .word   _estack
      .word   Reset_Handler
      .word   NMI_Handler
      .word   HardFault_Handler
      .word   MemManage_Handler
      .word   BusFault_Handler
      .word   UsageFault_Handler
      .word   0
      .word   0
      .word   0
      .word   0
      .word   SVC_Handler
      .word   DebugMon_Handler
      .word   0
      .word   PendSV_Handler
      .word   SysTick_Handler
      .word   WWDG_IRQHandler
      .word   PVD_PVM_IRQHandler
      .word   TAMP_STAMP_IRQHandler
      .word   RTC_WKUP_IRQHandler
      .word   FLASH_IRQHandler
      .word   RCC_IRQHandler
      .word   EXTI0_IRQHandler
      .word   EXTI1_IRQHandler
      .word   EXTI2_IRQHandler
      .word   EXTI3_IRQHandler
      .word   EXTI4_IRQHandler
      .word   DMA1_Channel1_IRQHandler
      .word   DMA1_Channel2_IRQHandler
      .word   DMA1_Channel3_IRQHandler
      .word   DMA1_Channel4_IRQHandler
      .word   DMA1_Channel5_IRQHandler
      .word   DMA1_Channel6_IRQHandler
      .word   DMA1_Channel7_IRQHandler
      .word   ADC1_2_IRQHandler
      .word   CAN1_TX_IRQHandler
      .word   CAN1_RX0_IRQHandler
      .word   CAN1_RX1_IRQHandler
      .word   CAN1_SCE_IRQHandler
      .word   EXTI9_5_IRQHandler
      .word   TIM1_BRK_TIM15_IRQHandler
      .word   TIM1_UP_TIM16_IRQHandler
      .word   TIM1_TRG_COM_TIM17_IRQHandler
      .word   TIM1_CC_IRQHandler
      .word   TIM2_IRQHandler
      .word   TIM3_IRQHandler
      .word   TIM4_IRQHandler
      .word   I2C1_EV_IRQHandler
      .word   I2C1_ER_IRQHandler
      .word   I2C2_EV_IRQHandler
      .word   I2C2_ER_IRQHandler
      .word   SPI1_IRQHandler
      .word   SPI2_IRQHandler
      .word   USART1_IRQHandler
      .word   USART2_IRQHandler
      .word   USART3_IRQHandler
      .word   EXTI15_10_IRQHandler
      .word   RTC_Alarm_IRQHandler
      .word   DFSDM1_FLT3_IRQHandler
      .word   TIM8_BRK_IRQHandler
      .word   TIM8_UP_IRQHandler
      .word   TIM8_TRG_COM_IRQHandler
      .word   TIM8_CC_IRQHandler
      .word   ADC3_IRQHandler
      .word   FMC_IRQHandler
      .word   SDMMC1_IRQHandler
      .word   TIM5_IRQHandler
      .word   SPI3_IRQHandler
      .word   UART4_IRQHandler
      .word   UART5_IRQHandler
      .word   TIM6_DAC_IRQHandler
      .word   TIM7_IRQHandler
      .word   DMA2_Channel1_IRQHandler
      .word   DMA2_Channel2_IRQHandler
      .word   DMA2_Channel3_IRQHandler
      .word   DMA2_Channel4_IRQHandler
      .word   DMA2_Channel5_IRQHandler
      .word   DFSDM1_FLT0_IRQHandler
      .word   DFSDM1_FLT1_IRQHandler
      .word   DFSDM1_FLT2_IRQHandler
      .word   COMP_IRQHandler
      .word   LPTIM1_IRQHandler
      .word   LPTIM2_IRQHandler
      .word   OTG_FS_IRQHandler
      .word   DMA2_Channel6_IRQHandler
      .word   DMA2_Channel7_IRQHandler
      .word   LPUART1_IRQHandler
      .word   QUADSPI_IRQHandler
      .word   I2C3_EV_IRQHandler
      .word   I2C3_ER_IRQHandler
      .word   SAI1_IRQHandler
      .word   SAI2_IRQHandler
      .word   SWPMI1_IRQHandler
      .word   TSC_IRQHandler
      .word   LCD_IRQHandler
      .word 0
      .word   RNG_IRQHandler
      .word   FPU_IRQHandler
  
  
  /*******************************************************************************
  *
  * Provide weak aliases for each Exception handler to the Default_Handler.
  * As they are weak aliases, any function with the same name will override
  * this definition.
  *
  *******************************************************************************/
  
    .weak NMI_Handler
      .thumb_set NMI_Handler,Default_Handler
  
    .weak HardFault_Handler
      .thumb_set HardFault_Handler,Default_Handler
  
    .weak MemManage_Handler
      .thumb_set MemManage_Handler,Default_Handler
  
    .weak BusFault_Handler
      .thumb_set BusFault_Handler,Default_Handler
  
      .weak   UsageFault_Handler
      .thumb_set UsageFault_Handler,Default_Handler
  
      .weak   SVC_Handler
      .thumb_set SVC_Handler,Default_Handler
  
      .weak   DebugMon_Handler
      .thumb_set DebugMon_Handler,Default_Handler
  
      .weak   PendSV_Handler
      .thumb_set PendSV_Handler,Default_Handler
  
      .weak   SysTick_Handler
      .thumb_set SysTick_Handler,Default_Handler
  
      .weak   WWDG_IRQHandler
      .thumb_set WWDG_IRQHandler,Default_Handler
  
      .weak   PVD_PVM_IRQHandler
      .thumb_set PVD_PVM_IRQHandler,Default_Handler
  
      .weak   TAMP_STAMP_IRQHandler
      .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
  
      .weak   RTC_WKUP_IRQHandler
      .thumb_set RTC_WKUP_IRQHandler,Default_Handler
  
      .weak   FLASH_IRQHandler
      .thumb_set FLASH_IRQHandler,Default_Handler
  
      .weak   RCC_IRQHandler
      .thumb_set RCC_IRQHandler,Default_Handler
  
      .weak   EXTI0_IRQHandler
      .thumb_set EXTI0_IRQHandler,Default_Handler
  
      .weak   EXTI1_IRQHandler
      .thumb_set EXTI1_IRQHandler,Default_Handler
  
      .weak   EXTI2_IRQHandler
      .thumb_set EXTI2_IRQHandler,Default_Handler
  
      .weak   EXTI3_IRQHandler
      .thumb_set EXTI3_IRQHandler,Default_Handler
  
      .weak   EXTI4_IRQHandler
      .thumb_set EXTI4_IRQHandler,Default_Handler
  
      .weak   DMA1_Channel1_IRQHandler
      .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
  
      .weak   DMA1_Channel2_IRQHandler
      .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
  
      .weak   DMA1_Channel3_IRQHandler
      .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
  
      .weak   DMA1_Channel4_IRQHandler
      .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
  
      .weak   DMA1_Channel5_IRQHandler
      .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
  
      .weak   DMA1_Channel6_IRQHandler
      .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
  
      .weak   DMA1_Channel7_IRQHandler
      .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
  
      .weak   ADC1_2_IRQHandler
      .thumb_set ADC1_2_IRQHandler,Default_Handler
  
      .weak   CAN1_TX_IRQHandler
      .thumb_set CAN1_TX_IRQHandler,Default_Handler
  
      .weak   CAN1_RX0_IRQHandler
      .thumb_set CAN1_RX0_IRQHandler,Default_Handler
  
      .weak   CAN1_RX1_IRQHandler
      .thumb_set CAN1_RX1_IRQHandler,Default_Handler
  
      .weak   CAN1_SCE_IRQHandler
      .thumb_set CAN1_SCE_IRQHandler,Default_Handler
  
      .weak   EXTI9_5_IRQHandler
      .thumb_set EXTI9_5_IRQHandler,Default_Handler
  
      .weak   TIM1_BRK_TIM15_IRQHandler
      .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler
  
      .weak   TIM1_UP_TIM16_IRQHandler
      .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler
  
      .weak   TIM1_TRG_COM_TIM17_IRQHandler
      .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler
  
      .weak   TIM1_CC_IRQHandler
      .thumb_set TIM1_CC_IRQHandler,Default_Handler
  
      .weak   TIM2_IRQHandler
      .thumb_set TIM2_IRQHandler,Default_Handler
  
      .weak   TIM3_IRQHandler
      .thumb_set TIM3_IRQHandler,Default_Handler
  
      .weak   TIM4_IRQHandler
      .thumb_set TIM4_IRQHandler,Default_Handler
  
      .weak   I2C1_EV_IRQHandler
      .thumb_set I2C1_EV_IRQHandler,Default_Handler
  
      .weak   I2C1_ER_IRQHandler
      .thumb_set I2C1_ER_IRQHandler,Default_Handler
  
      .weak   I2C2_EV_IRQHandler
      .thumb_set I2C2_EV_IRQHandler,Default_Handler
  
      .weak   I2C2_ER_IRQHandler
      .thumb_set I2C2_ER_IRQHandler,Default_Handler
  
      .weak   SPI1_IRQHandler
      .thumb_set SPI1_IRQHandler,Default_Handler
  
      .weak   SPI2_IRQHandler
      .thumb_set SPI2_IRQHandler,Default_Handler
  
      .weak   USART1_IRQHandler
      .thumb_set USART1_IRQHandler,Default_Handler
  
      .weak   USART2_IRQHandler
      .thumb_set USART2_IRQHandler,Default_Handler
  
      .weak   USART3_IRQHandler
      .thumb_set USART3_IRQHandler,Default_Handler
  
      .weak   EXTI15_10_IRQHandler
      .thumb_set EXTI15_10_IRQHandler,Default_Handler
  
      .weak   RTC_Alarm_IRQHandler
      .thumb_set RTC_Alarm_IRQHandler,Default_Handler
  
      .weak   DFSDM1_FLT3_IRQHandler
      .thumb_set DFSDM1_FLT3_IRQHandler,Default_Handler
  
      .weak   TIM8_BRK_IRQHandler
      .thumb_set TIM8_BRK_IRQHandler,Default_Handler
  
      .weak   TIM8_UP_IRQHandler
      .thumb_set TIM8_UP_IRQHandler,Default_Handler
  
      .weak   TIM8_TRG_COM_IRQHandler
      .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler
  
      .weak   TIM8_CC_IRQHandler
      .thumb_set TIM8_CC_IRQHandler,Default_Handler
  
      .weak   ADC3_IRQHandler
      .thumb_set ADC3_IRQHandler,Default_Handler
  
      .weak   FMC_IRQHandler
      .thumb_set FMC_IRQHandler,Default_Handler
  
      .weak   SDMMC1_IRQHandler
      .thumb_set SDMMC1_IRQHandler,Default_Handler
  
      .weak   TIM5_IRQHandler
      .thumb_set TIM5_IRQHandler,Default_Handler
  
      .weak   SPI3_IRQHandler
      .thumb_set SPI3_IRQHandler,Default_Handler
  
      .weak   UART4_IRQHandler
      .thumb_set UART4_IRQHandler,Default_Handler
  
      .weak   UART5_IRQHandler
      .thumb_set UART5_IRQHandler,Default_Handler
  
      .weak   TIM6_DAC_IRQHandler
      .thumb_set TIM6_DAC_IRQHandler,Default_Handler
  
      .weak   TIM7_IRQHandler
      .thumb_set TIM7_IRQHandler,Default_Handler
  
      .weak   DMA2_Channel1_IRQHandler
      .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
  
      .weak   DMA2_Channel2_IRQHandler
      .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
  
      .weak   DMA2_Channel3_IRQHandler
      .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
  
      .weak   DMA2_Channel4_IRQHandler
      .thumb_set DMA2_Channel4_IRQHandler,Default_Handler
  
      .weak   DMA2_Channel5_IRQHandler
      .thumb_set DMA2_Channel5_IRQHandler,Default_Handler
  
      .weak   DFSDM1_FLT0_IRQHandler
      .thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler   
  
      .weak   DFSDM1_FLT1_IRQHandler
      .thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler   
  
      .weak   DFSDM1_FLT2_IRQHandler
      .thumb_set DFSDM1_FLT2_IRQHandler,Default_Handler   
  
      .weak   COMP_IRQHandler
      .thumb_set COMP_IRQHandler,Default_Handler
  
      .weak   LPTIM1_IRQHandler
      .thumb_set LPTIM1_IRQHandler,Default_Handler
  
      .weak   LPTIM2_IRQHandler
      .thumb_set LPTIM2_IRQHandler,Default_Handler    
  
      .weak   OTG_FS_IRQHandler
      .thumb_set OTG_FS_IRQHandler,Default_Handler    
  
      .weak   DMA2_Channel6_IRQHandler
      .thumb_set DMA2_Channel6_IRQHandler,Default_Handler 
  
      .weak   DMA2_Channel7_IRQHandler
      .thumb_set DMA2_Channel7_IRQHandler,Default_Handler 
  
      .weak   LPUART1_IRQHandler
      .thumb_set LPUART1_IRQHandler,Default_Handler   
  
      .weak   QUADSPI_IRQHandler
      .thumb_set QUADSPI_IRQHandler,Default_Handler   
  
      .weak   I2C3_EV_IRQHandler
      .thumb_set I2C3_EV_IRQHandler,Default_Handler   
  
      .weak   I2C3_ER_IRQHandler
      .thumb_set I2C3_ER_IRQHandler,Default_Handler   
  
      .weak   SAI1_IRQHandler
      .thumb_set SAI1_IRQHandler,Default_Handler
  
      .weak   SAI2_IRQHandler
      .thumb_set SAI2_IRQHandler,Default_Handler
  
      .weak   SWPMI1_IRQHandler
      .thumb_set SWPMI1_IRQHandler,Default_Handler
  
      .weak   TSC_IRQHandler
      .thumb_set TSC_IRQHandler,Default_Handler
  
      .weak   LCD_IRQHandler
      .thumb_set LCD_IRQHandler,Default_Handler
  
      .weak   RNG_IRQHandler
      .thumb_set RNG_IRQHandler,Default_Handler
  
      .weak   FPU_IRQHandler
      .thumb_set FPU_IRQHandler,Default_Handler
  /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  </code></pre>
  
  <p>Reset_Handler from my above startup Code:</p>
  
  <pre><code>   .section .text.Reset_Handler
      .weak   Reset_Handler
      .type   Reset_Handler, %function
  Reset_Handler:
    ldr   sp, =_estack    /* Atollic update: set stack pointer */
  
  /* Copy the data segment initializers from flash to SRAM */
    movs  r1, #0
    b LoopCopyDataInit
  
  CopyDataInit:
      ldr r3, =_sidata
      ldr r3, [r3, r1]
      str r3, [r0, r1]
      adds    r1, r1, #4
  
  LoopCopyDataInit:
      ldr r0, =_sdata
      ldr r3, =_edata
      adds    r2, r0, r1
      cmp r2, r3
      bcc CopyDataInit
      ldr r2, =_sbss
      b   LoopFillZerobss
  /* Zero fill the bss segment. */
  FillZerobss:
      movs    r3, #0
      str r3, [r2], #4
  
  LoopFillZerobss:
      ldr r3, = _ebss
      cmp r2, r3
      bcc FillZerobss
  
  /* Call the clock system intitialization function.*/
      bl  SystemInit
  /* Call static constructors */
      bl __libc_init_array
  /* Call the application's entry point.*/
      bl  main
  
  LoopForever:
      b LoopForever
  
  .size   Reset_Handler, .-Reset_Handler
  </code></pre>
  
  <p>My PlatformIO build configurations are as follow:</p>
  
  <pre><code>[env:disco_l476vg]
  platform = ststm32@4.5.0
  board = disco_l476vg
  framework = stm32cube
  build_flags = -g -O0 -mfloat-abi=softfp -mfpu=fpv5-d16
  upload_protocol = stlink
  extra_scripts = update_link_flags.py
  </code></pre>