gpt4 book ai didi

c - GCC 链接器,bss 部分符号等于零长度

转载 作者:行者123 更新时间:2023-12-04 17:55:50 28 4
gpt4 key购买 nike

为了试图理解基础知识,我编写了 [或提取了我猜] 以下 c 代码和链接器脚本。生成的二进制文件可以正常工作,并且 LED 闪烁没有问题。但是,在调试时,我发现 bss_start bss_end 符号都包含 0x20000000 的值。基本跳过了 bss 零功能。在进行 objdump 时,我可以看到

20000000 g O .bss 00000004 timer_delayCount

所以该部分有 4 个字节长,位于 0x20000000 正确位置。并且至少 bss_start 指向正确的内存地址。然而, bss_end 应该指向 0x20000004 [我认为],而不是 0x20000000。

我想现在乳清 bss_end 符号在 *(.bss) 之后没有增加,我认为它包含四个字节。

微 Controller 是stm32f103rb,一个cortex-m3芯片。我正在遵守 ARM GNU GCC

我的 main.c 文件:

#define _stackInit 0x20005000U

volatile unsigned int * const RCC_APB2ENR = (unsigned int *)0x40021018;
volatile unsigned int * const GPIOA_CRL = (unsigned int *)0x40010800;
volatile unsigned int * const GPIOA_BSR = (unsigned int *)0x40010810;
volatile unsigned int * const GPIOA_BRR = (unsigned int *)0x40010814;
volatile unsigned int * const STK_CTRL = (unsigned int *)0xE000E010;
volatile unsigned int * const STK_LOAD = (unsigned int *)0xE000E014;
volatile unsigned int * const STK_VAL = (unsigned int *)0xE000E018;

volatile unsigned int timer_delayCount;

int main() {
// enable GIOA clock and set PB5 to output
*RCC_APB2ENR |= (unsigned int)0x00000004;
*GPIOA_CRL = (unsigned int)0x44244444;

// COnfigure Systick Timer for 1 millisecond interrupts
*STK_VAL = 0x00;
*STK_LOAD = 7999U; //tick every 1 ms
*STK_CTRL = 0x07;


while (1){
int c, d;
timer_delayCount = 500u;
while(timer_delayCount != 0u);
*GPIOA_BSR = 0x20;

timer_delayCount = 500u;
while(timer_delayCount != 0u);
*GPIOA_BRR = 0x20;
}

}


// Begin and End addresses for the .bss section. Symbols defined in linker script
extern unsigned int __bss_start__;
extern unsigned int __bss_end__;

void __attribute__ ((section(".after_vectors"))) Reset_Handler (void)
{

// Initialize bss section by iterating and clearing word by word.
// It is assumed that the pointers are word aligned.
unsigned int *p = &__bss_start__;
while (p < &__bss_end__) {
*p++ = 0;
}

main();
}

void SysTick_Handler() {
// Decrement to coutner to zero.
if (timer_delayCount != 0u)
{
--timer_delayCount;
}
}

void __attribute__ ((section(".after_vectors"))) Default_Handler(void)
{
while(1);
}

void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) NMI_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) HardFault_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) MemManage_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) BusFault_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) UsageFault_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) SVC_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) DebugMon_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) PendSV_Handler(void);

typedef void(* const pHandler)(void);

// The vector table.
// The linker script to place at correct location in memory.
__attribute__ ((section(".isr_vector"),used)) pHandler __isr_vectors[] =
{
//core exceptions
(pHandler)_stackInit, // Inital Stack Pointer
Reset_Handler, // reset handler
NMI_Handler, // NMI handler
HardFault_Handler, // hard fault handler
MemManage_Handler, // MPU fault handler
BusFault_Handler, // bus fault handler
UsageFault_Handler, // usage fault handler
0x00, // reserved
0x00, // reserved
0x00, // reserved
0x00, // reserved
SVC_Handler, // SVCall handler
DebugMon_Handler, // debug monitor handler
0x00, // reserved
PendSV_Handler, // PendSV handler
SysTick_Handler, // systick handler
};

我的链接器文件:
ENTRY(Reset_Handler)

MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
}


SECTIONS
{
.text : {
*(.isr_vector)
*(.after_vectors)
*(.text)
} > FLASH

.bss : {
__bss_start__ = .; /* symbol for c code to initialize bss section */
*(.bss)
__bss_end__ = .; /* symbol for c code to initialize bss section */
} > RAM
}

编译器命令:
/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-gcc -c -mcpu=cortex-m3 -mthumb -g blinky-interrupt.c -o blinky-interrupt.o
/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-ld -T blinky-interrupt.ld blinky-interrupt.o -o blinky-interrupt.elf

最佳答案

那是因为一个未初始化的变量进入 COMMON instead of .bss .如果你用 0 初始化它,那么它会进入 .bss .

查看链接器映射文件(如果你没有,让链接器用 -Map 生成它),你应该看到这样的东西

.bss            0x0000000020000000        0x4 load address 0x00000000080000e0
0x0000000020000000 . = ALIGN (0x4)
0x0000000020000000 __bss_start__ = .
*(.bss)
0x0000000020000000 . = ALIGN (0x4)
0x0000000020000000 __bss_end__ = .
COMMON 0x0000000020000000 0x4 ./src/app/main.o
0x0000000020000000 timer_delayCount

COMMON未在链接器脚本中指定,链接器将它放在其他地方,可能会在最后转储它。

更完整的链接描述文件有以下 .bss部分
  .bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} >RAM

然后是 COMMON部分将在 __bss_start__ 之间和 __bss_end__ .

仅供引用, *(.bss*)有没有覆盖 -fdata-sections选项,当每个变量都有自己的段时,链接器可以删除未引用的段。

关于c - GCC 链接器,bss 部分符号等于零长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50040272/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com