Почему компоновщик GCC помещает 8 байтов пространства между этими двумя разделами?

Моя общая цель — иметь возможность вычислить контрольную сумму с помощью встроенного периферийного устройства CRC, чтобы я мог убедиться, что двоичный файл был правильно записан на плату. У меня есть рабочий скрипт Python, который просто копирует то, что делает периферийное устройство CRC, и затем я передаю его в файл .bin, чтобы получить контрольную сумму.

Пытаясь заставить мой скрипт работать, я заметил, что между разделами .isr_vector и разделами .text есть 8 байтов пространства, которые не совпадают между флэш-памятью и самим двоичным файлом. При отладке чипа все эти 8 байтов имеют размер 0xFF, но в двоичном виде они равны 0x00. Я знаю, что по умолчанию чип использует все 1, поэтому у меня есть смутное представление, почему они разные (или, по крайней мере, я так думаю), но я не знаю, почему вообще существует это пространство.

Большую часть вчерашнего вечера я провел, играя со сценарием компоновщика, перемещая флаги выравнивания и играя со значениями заполнения/дополнения. Использование «FILL(0xFF);» не влияет на это пространство, равно как и установка «=0xFF» в конце раздела. Флаги выравнивания перемещают объекты, но не оказывают никакого влияния на пространство. Мне удалось заполнить его (а также окончательно убедиться, что мой сценарий соответствует периферийному устройству CRC), вставив «BYTE (0xFF);» 8 раз в конце раздела, но мне это кажется хакерским обходным путем.

Что это за пространство, почему оно там, как мне от него изящно избавиться, будут ли за это последствия?

Мой скрипт компоновщика с моим хакерским исправлением. Если удалить строки 29-38, появится «пробел». Первоначально он был сгенерирован CubeIDE, но с тех пор я довольно долго над ним ковырялся. Это мой первый значимый набег на сценарии лайков, поэтому, возможно, я делаю что-то ужасно неправильно.

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM);    /* end of RAM */

/* Usedd to generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;  /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

_code_size = SIZEOF(.isr_vector) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ARM);
vector_size = SIZEOF(.isr_vector);

/* Specify the memory areas */
MEMORY
{
    RAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 32K
    FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
}

/* Define output sections */
SECTIONS
{
    /* The startup code goes first into FLASH */
    .isr_vector :
    {
        KEEP(*(.isr_vector)) /* Startup code */

        /* These are the 8 bytes that "fix" the problem, without these the space is filled with zeros */
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
        BYTE(0xFF);
    } >FLASH =0xEE

    /* The program code and other data goes into FLASH */
    .text : ALIGN(4)
    {
        BYTE(vector_size);
        *(.text)           /* .text sections (code) */
        *(.text*)          /* .text* sections (code) */

        KEEP (*(.init))
        KEEP (*(.fini))

        . = ALIGN(4);
        _etext = .;        /* define a global symbols at end of code */
    } >FLASH =0xEE

    /* Constant data goes into FLASH */
    .rodata : ALIGN(4)
    {
        *(.rodata)         /* .rodata sections (constants, strings, etc.) */
        *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    } >FLASH =0xEE

    .ARM (READONLY) : ALIGN(4)
    {
        __exidx_start = .;
        *(.ARM.exidx*)
        __exidx_end = .;
    } >FLASH =0xEE

    /* used by the startup to initialize data */
    _sidata = LOADADDR(.data);

    /* Initialized data sections goes into RAM, load LMA copy after code */
    .data : 
    {
        . = ALIGN(4);
        _sdata = .;        /* create a global symbol at data start */
        *(.data)           /* .data sections */
        *(.data*)          /* .data* sections */

        . = ALIGN(4);
        _edata = .;        /* define a global symbol at data end */
    } >RAM AT> FLASH

    
    /* Uninitialized data section */
    . = ALIGN(4);
    .bss :
    {
        /* This is used by the startup in order to initialize the .bss secion */
        _sbss = .;         /* define a global symbol at bss start */
        __bss_start__ = _sbss;
        *(.bss)
        *(.bss*)
        *(COMMON)

        . = ALIGN(4);
        _ebss = .;         /* define a global symbol at bss end */
        __bss_end__ = _ebss;
    } >RAM

    /* User_heap_stack section, used to check that there is enough RAM left */
    ._user_heap_stack :
    {
        . = ALIGN(8);
        PROVIDE ( end = . );
        PROVIDE ( _end = . );
        . = . + _Min_Heap_Size;
        . = . + _Min_Stack_Size;
        . = ALIGN(8);
    } >RAM

    /* Remove information from the standard libraries */
    /DISCARD/ :
    {
        libc.a ( * )
        libm.a ( * )
        libgcc.a ( * )
    }

    .ARM.attributes 0 :
    {
        *(.ARM.attributes)
    }
}

Вот начало моего кода. Он также в основном создан CubeIDE с некоторыми небольшими изменениями.

  .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   r0, =_estack
  mov   sp, r0          /* set stack pointer */
  
/* Call the clock system initialization function.*/
  bl  SystemInit

/* Copy the data segment initializers from flash to SRAM */
  ldr r0, =_sdata
  ldr r1, =_edata
  ldr r2, =_sidata
  movs r3, #0
  b LoopCopyDataInit

CopyDataInit:
  ldr r4, [r2, r3]
  str r4, [r0, r3]
  adds r3, r3, #4

LoopCopyDataInit:
  adds r4, r0, r3
  cmp r4, r1
  bcc CopyDataInit
  
/* Zero fill the bss segment. */
  ldr r2, =_sbss
  ldr r4, =_ebss
  movs r3, #0
  b LoopFillZerobss

FillZerobss:
  str  r3, [r2]
  adds r2, r2, #4

LoopFillZerobss:
  cmp r2, r4
  bcc FillZerobss
/* 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


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   RTC_TAMP_LSECSS_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   0
    .word   ADC1_2_IRQHandler
    .word   USB_HP_IRQHandler
    .word   USB_LP_IRQHandler
    .word   can_isr
    .word   can_isr
    .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   USBWakeUp_IRQHandler
    .word   TIM8_BRK_IRQHandler
    .word   TIM8_UP_IRQHandler
    .word   TIM8_TRG_COM_IRQHandler
    .word   TIM8_CC_IRQHandler
    .word   0
    .word   0
    .word   LPTIM1_IRQHandler
    .word   0
    .word   SPI3_IRQHandler
    .word   UART4_IRQHandler
    .word   0
    .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   0
    .word   0
    .word   UCPD1_IRQHandler
    .word   COMP1_2_3_IRQHandler
    .word   COMP4_IRQHandler
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   CRS_IRQHandler
    .word   SAI1_IRQHandler
    .word   0
    .word   0
    .word   0
    .word   0
    .word   FPU_IRQHandler
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   RNG_IRQHandler
    .word   LPUART1_IRQHandler
    .word   I2C3_EV_IRQHandler
    .word   I2C3_ER_IRQHandler
    .word   DMAMUX_OVR_IRQHandler
    .word   0
    .word   0
    .word   DMA2_Channel6_IRQHandler
    .word   0
    .word   0
    .word   CORDIC_IRQHandler
    .word   FMAC_IRQHandler

    .size   g_pfnVectors, .-g_pfnVectors

/*******************************************************************************
*
* 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   RTC_TAMP_LSECSS_IRQHandler
    .thumb_set RTC_TAMP_LSECSS_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   ADC1_2_IRQHandler
    .thumb_set ADC1_2_IRQHandler,Default_Handler

    .weak   USB_HP_IRQHandler
    .thumb_set USB_HP_IRQHandler,Default_Handler

    .weak   USB_LP_IRQHandler
    .thumb_set USB_LP_IRQHandler,Default_Handler

    .weak   can_isr
    .thumb_set can_isr,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   USBWakeUp_IRQHandler
    .thumb_set USBWakeUp_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   LPTIM1_IRQHandler
    .thumb_set LPTIM1_IRQHandler,Default_Handler

    .weak   SPI3_IRQHandler
    .thumb_set SPI3_IRQHandler,Default_Handler

    .weak   UART4_IRQHandler
    .thumb_set UART4_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   UCPD1_IRQHandler
    .thumb_set UCPD1_IRQHandler,Default_Handler

    .weak   COMP1_2_3_IRQHandler
    .thumb_set COMP1_2_3_IRQHandler,Default_Handler

    .weak   COMP4_IRQHandler
    .thumb_set COMP4_IRQHandler,Default_Handler

    .weak   CRS_IRQHandler
    .thumb_set CRS_IRQHandler,Default_Handler

    .weak   SAI1_IRQHandler
    .thumb_set SAI1_IRQHandler,Default_Handler

    .weak   FPU_IRQHandler
    .thumb_set FPU_IRQHandler,Default_Handler

    .weak   RNG_IRQHandler
    .thumb_set RNG_IRQHandler,Default_Handler

    .weak   LPUART1_IRQHandler
    .thumb_set LPUART1_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   DMAMUX_OVR_IRQHandler
    .thumb_set DMAMUX_OVR_IRQHandler,Default_Handler

    .weak   DMA2_Channel6_IRQHandler
    .thumb_set DMA2_Channel6_IRQHandler,Default_Handler

    .weak   CORDIC_IRQHandler
    .thumb_set CORDIC_IRQHandler,Default_Handler

    .weak   FMAC_IRQHandler
    .thumb_set FMAC_IRQHandler,Default_Handler

Скриншот двоичного файла, открытого в шестнадцатеричном виде. Строка 1D8 содержит пробел, на который я жалуюсь. Без 8 инструкций «BYTE(0xFF)» это выглядит как нули.

Я использую MSYS2 GCC версии 14.1.0 для компиляции и связывания микроконтроллера STMG4.

Я использую make для сборки, команда make запускает ссылку:

gcc -O0 -g3 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Wall -MMD -fdata-sections -ffunction-sections ${INCLUDE_FLAGS} -DSTM32G431xx -DUSE_HAL_DRIVER -T "${LINKER_SCRIPT}" --specs=nano.specs -Wl,-Map=${OUTPUT_DIR}${SOFTWARE_VERSION}.map -Wl,--gc-sections -Wl,--start-group -lc -lm -Wl,--end-group -Wl,-static ${addprefix ${OBJECT_DIR}, ${OBJECTS}} -o ${OUTPUT_DIR}${SOFTWARE_VERSION}.elf

Это файл карты после удаления практически всего кода, кроме показанной ранее стартовой сборки, пустой основной функции и пустой функции SystemInit (вызываемой в строке 40 файла стартовой сборки). Что-то, что я сделал, удалив весь остальной код, кажется, решил мою проблему, хотя я до сих пор не понял, почему.

                0x20008000                        _estack = (ORIGIN (RAM) + LENGTH (RAM))
                0x00000200                        _Min_Heap_Size = 0x200
                0x00000400                        _Min_Stack_Size = 0x400
                0x000002ac                        _code_size = (((SIZEOF (.isr_vector) + SIZEOF (.text)) + SIZEOF (.rodata)) + SIZEOF (.ARM))
                0x000001d8                        vector_size = SIZEOF (.isr_vector)

.isr_vector     0x08000000      0x1d8
 *(.isr_vector)
 .isr_vector    0x08000000      0x1d8 build/obj/startup_stm32g431kbtx.o
                0x08000000                g_pfnVectors

.text           0x080001d8       0xd4
 *(.text)
 *(.text*)
 .text.__libc_init_array
                0x080001d8       0x48 C:\...d\libc_nano.a(libc_a-init.o)
                0x080001d8                __libc_init_array
 .text.main     0x08000220       0x10 build/obj/main.o
                0x08000220                main
 .text.SystemInit
                0x08000230        0xe build/obj/main.o
                0x08000230                SystemInit
 *fill*         0x0800023e        0x2 ee
 .text.Reset_Handler
                0x08000240       0x50 build/obj/startup_stm32g431kbtx.o
                0x08000240                Reset_Handler
 .text.Default_Handler
                0x08000290        0x2 build/obj/startup_stm32g431kbtx.o
                0x08000290                RTC_Alarm_IRQHandler
                0x08000290                EXTI2_IRQHandler
                0x08000290                TIM8_TRG_COM_IRQHandler
                0x08000290                TIM8_CC_IRQHandler
                0x08000290                DebugMon_Handler
                0x08000290                TIM1_CC_IRQHandler
                0x08000290                HardFault_Handler
                0x08000290                USB_HP_IRQHandler
                0x08000290                CORDIC_IRQHandler
                0x08000290                SysTick_Handler
                0x08000290                PendSV_Handler
                0x08000290                NMI_Handler
                0x08000290                EXTI3_IRQHandler
                0x08000290                I2C3_ER_IRQHandler
                0x08000290                EXTI0_IRQHandler
                0x08000290                I2C2_EV_IRQHandler
                0x08000290                FPU_IRQHandler
                0x08000290                TIM1_UP_TIM16_IRQHandler
                0x08000290                UsageFault_Handler
                0x08000290                ADC1_2_IRQHandler
                0x08000290                SPI1_IRQHandler
                0x08000290                TIM6_DAC_IRQHandler
                0x08000290                TIM8_UP_IRQHandler
                0x08000290                DMA2_Channel2_IRQHandler
                0x08000290                DMA1_Channel4_IRQHandler
                0x08000290                USART3_IRQHandler
                0x08000290                TIM4_IRQHandler
                0x08000290                DMA2_Channel1_IRQHandler
                0x08000290                I2C1_EV_IRQHandler
                0x08000290                DMA1_Channel6_IRQHandler
                0x08000290                UART4_IRQHandler
                0x08000290                DMA2_Channel4_IRQHandler
                0x08000290                TIM3_IRQHandler
                0x08000290                RCC_IRQHandler
                0x08000290                DMA1_Channel1_IRQHandler
                0x08000290                Default_Handler
                0x08000290                RTC_TAMP_LSECSS_IRQHandler
                0x08000290                FMAC_IRQHandler
                0x08000290                EXTI15_10_IRQHandler
                0x08000290                TIM7_IRQHandler
                0x08000290                UCPD1_IRQHandler
                0x08000290                I2C3_EV_IRQHandler
                0x08000290                EXTI9_5_IRQHandler
                0x08000290                RTC_WKUP_IRQHandler
                0x08000290                PVD_PVM_IRQHandler
                0x08000290                SPI2_IRQHandler
                0x08000290                MemManage_Handler
                0x08000290                can_isr
                0x08000290                SVC_Handler
                0x08000290                DMA2_Channel5_IRQHandler
                0x08000290                CRS_IRQHandler
                0x08000290                DMA1_Channel5_IRQHandler
                0x08000290                USB_LP_IRQHandler
                0x08000290                EXTI4_IRQHandler
                0x08000290                RNG_IRQHandler
                0x08000290                TIM1_TRG_COM_TIM17_IRQHandler
                0x08000290                DMA1_Channel3_IRQHandler
                0x08000290                WWDG_IRQHandler
                0x08000290                LPUART1_IRQHandler
                0x08000290                DMA2_Channel6_IRQHandler
                0x08000290                TIM2_IRQHandler
                0x08000290                COMP1_2_3_IRQHandler
                0x08000290                EXTI1_IRQHandler
                0x08000290                USART2_IRQHandler
                0x08000290                I2C2_ER_IRQHandler
                0x08000290                DMA1_Channel2_IRQHandler
                0x08000290                TIM8_BRK_IRQHandler
                0x08000290                FLASH_IRQHandler
                0x08000290                BusFault_Handler
                0x08000290                USART1_IRQHandler
                0x08000290                SPI3_IRQHandler
                0x08000290                I2C1_ER_IRQHandler
                0x08000290                LPTIM1_IRQHandler
                0x08000290                DMAMUX_OVR_IRQHandler
                0x08000290                USBWakeUp_IRQHandler
                0x08000290                SAI1_IRQHandler
                0x08000290                DMA2_Channel3_IRQHandler
                0x08000290                COMP4_IRQHandler
                0x08000290                TIM1_BRK_TIM15_IRQHandler
 *(.init)
 *fill*         0x08000292        0x2 ee
 .init          0x08000294        0x4 C:/.../crti.o
                0x08000294                _init
 .init          0x08000298        0x8 C:/.../crtn.o
 *(.fini)
 .fini          0x080002a0        0x4 C:/.../crti.o
                0x080002a0                _fini
 .fini          0x080002a4        0x8 C:/.../crtn.o
                0x080002ac                        . = ALIGN (0x4)
                0x080002ac                        _etext = .

.glue_7         0x080002ac        0x0
 .glue_7        0x080002ac        0x0 linker stubs

.glue_7t        0x080002ac        0x0
 .glue_7t       0x080002ac        0x0 linker stubs

.vfp11_veneer   0x080002ac        0x0
 .vfp11_veneer  0x080002ac        0x0 linker stubs

.v4_bx          0x080002ac        0x0
 .v4_bx         0x080002ac        0x0 linker stubs

.iplt           0x080002ac        0x0
 .iplt          0x080002ac        0x0 C:/...\libc_nano.a(libc_a-init.o)

.rel.dyn        0x080002ac        0x0
 .rel.iplt      0x080002ac        0x0 C:/...\libc_nano.a(libc_a-init.o)

.rodata
 *(.rodata)
 *(.rodata*)

.ARM            0x080002ac        0x0
                0x080002ac                        __exidx_start = .
 *(.ARM.exidx*)
                0x080002ac                        __exidx_end = .
                0x080002ac                        _sidata = LOADADDR (.data)

.data           0x20000000        0x0 load address 0x080002ac
                0x20000000                        . = ALIGN (0x4)
                0x20000000                        _sdata = .
 *(.data)
 *(.data*)
                0x20000000                        . = ALIGN (0x4)
                0x20000000                        _edata = .

.igot.plt       0x20000000        0x0 load address 0x080002ac
 .igot.plt      0x20000000        0x0 C:/...\libc_nano.a(libc_a-init.o)
                0x20000000                        . = ALIGN (0x4)

.bss            0x20000000        0x0 load address 0x080002ac
                0x20000000                        _sbss = .
                0x20000000                        __bss_start__ = _sbss
 *(.bss)
 *(.bss*)
 *(COMMON)
                0x20000000                        . = ALIGN (0x4)
                0x20000000                        _ebss = .
                0x20000000                        __bss_end__ = _ebss

._user_heap_stack
                0x20000000      0x600 load address 0x080002ac
                0x20000000                        . = ALIGN (0x8)
                [!provide]                        PROVIDE (end = .)
                [!provide]                        PROVIDE (_end = .)
                0x20000200                        . = (. + _Min_Heap_Size)
 *fill*         0x20000000      0x200 
                0x20000600                        . = (. + _Min_Stack_Size)
 *fill*         0x20000200      0x400 
                0x20000600                        . = ALIGN (0x8)

/DISCARD/
 libc.a(*)
 libm.a(*)
 libgcc.a(*)

.ARM.attributes
                0x00000000       0x30
 *(.ARM.attributes)
 .ARM.attributes
                0x00000000       0x22 C:/.../crti.o
 .ARM.attributes
                0x00000022       0x34 C:/...\libc_nano.a(libc_a-init.o)
 .ARM.attributes
                0x00000056       0x34 build/obj/main.o
 .ARM.attributes
                0x0000008a       0x21 build/obj/startup_stm32g431kbtx.o
 .ARM.attributes
                0x000000ab       0x22 C:/.../crtn.o
OUTPUT(build/VERSION0/VERSION0.elf elf32-littlearm)
LOAD linker stubs
LOAD C:/...\libc.a
LOAD C:/...\libm.a
LOAD C:/...\libgcc.a

.debug_frame    0x00000000       0x7c
 .debug_frame   0x00000000       0x2c C:/...\libc_nano.a(libc_a-init.o)
 .debug_frame   0x0000002c       0x50 build/obj/main.o

.debug_info     0x00000000       0x8a
 .debug_info    0x00000000       0x5a build/obj/main.o
 .debug_info    0x0000005a       0x30 build/obj/startup_stm32g431kbtx.o

.debug_abbrev   0x00000000       0x79
 .debug_abbrev  0x00000000       0x55 build/obj/main.o
 .debug_abbrev  0x00000055       0x24 build/obj/startup_stm32g431kbtx.o

.debug_aranges  0x00000000       0x50
 .debug_aranges
                0x00000000       0x28 build/obj/main.o
 .debug_aranges
                0x00000028       0x28 build/obj/startup_stm32g431kbtx.o

.debug_rnglists
                0x00000000       0x32
 .debug_rnglists
                0x00000000       0x19 build/obj/main.o
 .debug_rnglists
                0x00000019       0x19 build/obj/startup_stm32g431kbtx.o

.debug_macro    0x00000000      0xac9
 .debug_macro   0x00000000       0x1b build/obj/main.o
 .debug_macro   0x0000001b      0xaae build/obj/main.o

.debug_line     0x00000000       0xce
 .debug_line    0x00000000       0x53 build/obj/main.o
 .debug_line    0x00000053       0x7b build/obj/startup_stm32g431kbtx.o

.debug_str      0x00000000     0x2e0b
 .debug_str     0x00000000     0x2dcf build/obj/main.o
 .debug_str     0x00002dcf       0x3c build/obj/startup_stm32g431kbtx.o
                                 0x7c (size before relaxing)

.comment        0x00000000       0x43
 .comment       0x00000000       0x43 build/obj/main.o
                                 0x44 (size before relaxing)

.debug_line_str
                0x00000000       0x60
 .debug_line_str
                0x00000000       0x60 build/obj/startup_stm32g431kbtx.o

Во-первых, размер вектора не умещается в байт, поэтому BYTE(vector_size) определенно не содержит того, что вы ожидаете, возможно, оно равно нулю. После этого вы, вероятно, получите 3 или 7 байтов заполнения для правильного выравнивания следующего объекта, который будет помещен в .text.

Tom V 30.07.2024 21:03

После этого не компилируйте и не компонуйте одной командой! Запустите objdump для промежуточных файлов (особенно файлов запуска), чтобы увидеть, что они содержат, и его выравнивание.

Tom V 30.07.2024 21:06

Кроме того, ваша команда ссылки выводит файл карты, как насчет редактирования вопроса, чтобы включить его?

Tom V 30.07.2024 21:06

«BYTE(vector_size)» — это просто какой-то мусор, который я случайно оставил там, когда пытался разобраться самостоятельно. Насколько я могу судить, на самом деле он ничего не делает, поэтому я удалил его снова. Я компилирую отдельно в своем make-файле, я просто повторно использую команду gcc для вызова ld. Понятия не имею, хорошая это практика или нет. Я беспокоюсь, что моя работа не будет в порядке, включая файл карты, потому что в нем слишком много служебной информации. Если вам нужен конкретный фрагмент или если без него просто невозможно ответить, я возьму, продезинфицирую его и опубликую.

Sonny 30.07.2024 21:56

@Sonny Если вы беспокоитесь о конфиденциальности, можете ли вы воспроизвести эту проблему с помощью проекта, в котором есть только код запуска и функция main(), которая ничего не делает?

pmacfarlane 30.07.2024 21:58

@pmacfarlane Я, конечно, могу попробовать!

Sonny 30.07.2024 21:59

Я добавил как можно большую часть файла карты. У меня исчерпан лимит символов, поэтому мне пришлось вырезать то, что, как я надеюсь, не имеет значения. Не обращайте внимания на пути к файлам, ни один из них не является правильным после того, как я их все вырезал.

Sonny 30.07.2024 22:34

По какой-то причине удаление всего кода, похоже, очистило пустое пространство, которое я видел (когда я также удалил 8 «BYTE (0xFF)»).

Sonny 30.07.2024 22:36

Кажется, он с удовольствием прикрепил .text.__libc_init_array к 0x1d8. Это делает это с вашей обычной сборкой? Возможно, по неизвестным причинам ему требуется .text.main на границе 16 байт.

pmacfarlane 31.07.2024 01:03

@pmacfarlane Нет, только когда я собираю его без инструкций «BYTE (0xFF)» и с сокращенным кодом.

Sonny 31.07.2024 01:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
10
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Что это за пространство, почему оно там, как мне от него изящно избавиться, будут ли за это последствия?

.text : ALIGN(4)

Это устанавливает раздел по новому адресу ALIGN(4). Между ними не определены данные. При выводе в двоичный файл неопределенное пространство по умолчанию равно 0x00. Если вы создали «ihex» или другой формат вывода, пробел будет просто пропущен.

Что-то, что я сделал, удалив весь остальной код, кажется, решил мою проблему, хотя я до сих пор не понял, почему.

Если вы измените код так, чтобы isr_vector совпадало с 2**4, эффективного пробела не будет.

Существует несколько решений.

  1. Убедитесь, что isr_vector дополняется до выравнивания следующего раздела text. Вы можете использовать ALIGN (или FILL, но ALIGN сделает математику за вас).
  2. Явно укажите код isr_vector в начале текста и удалите раздел isr_vector. Функции уже должны быть выровнены компилятором. Выравнивание разделов — это другой уровень.

Бонус: _user_heap_stack и _data имеют . = ALIGN(8) и . = ALIGN(4) в начале. Они ничего не делают. Файл компоновщика ._user_heap_stack:ALIGN(8) и .data:ALIGN(4) выполнит эту задачу.

Связанный:

Также имеется ошибка во встроенном модуле CRC STM32. Если вы его используете, я могу показать код, который исправляет его для использования стандартного алгоритма CRC.

artless noise 31.07.2024 15:12

Другие вопросы по теме