ARM二进制大小

Mar*_*sek 2 c++ binary arm stm32 bin

我正在使用ARM GCC noneabi编译器c / c ++对STM32F4 **和STM32F0 **之类的MCU进行编程,并发现了有趣的模式。

如果我构建一些* .bin文件,它的大小总是可以被4整除。

我认为可能是因为MCU是32位(= 4字节)。因此bin_size%4 == 0。我尝试了一些“技巧”;例如,将某个字节数组扩大1,但二进制大小始终相同。当我更多地扩大数组时,二进制大小会更大,但又可以被4整除。

我可以将此效应视为公理吗?

还是有一些情况不起作用?例如,是否可以将32位STM32 MCU切换到16位模式?还是可以用另一个编译器创建不可除二的二进制数?

ber*_*ing 5

可以创建任意大小的二进制文件,4字节对齐只是为了方便。每个人都这样,每个人都期望它。

对齐在链接脚本文件中强制执行。如果查看*.ld项目文件,您会发现其中有很多

. = ALIGN(4);
Run Code Online (Sandbox Code Playgroud)

陈述。它们指示链接器将当前输出地址推进到可以被4整除的值。

因此,我创建了一个空项目,并ALIGN从链接描述文件中删除了大多数代码行:

ENTRY(Reset_Handler)
__stack = 0x20014000;
MEMORY
{
FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 512K
RAM   (xrw)     : ORIGIN = 0x20000000, LENGTH = 80K
}
SECTIONS
{
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector))
    . = ALIGN(4);
  } >FLASH
  .text :
  {
    *(.text)
    *(.text*)
  } >FLASH
  .rodata :
  {
    *(.rodata)
    *(.rodata*)
  } >FLASH
  _sidata = LOADADDR(.data);
  .data : 
  {
    _sdata = .;
    *(.data)
    *(.data*)
    _edata = .;
  } >RAM AT> FLASH
  .bss :
  {
    _sbss = .;
    *(.bss)
    *(.bss*)
    *(COMMON)
    _ebss = .;
  } >RAM
}
Run Code Online (Sandbox Code Playgroud)

一个最小的程序:

void Reset_Handler(void) {
    while(1)
        ;
}
Run Code Online (Sandbox Code Playgroud)

编译并与链接-nostartfiles -nodefaultlibs -nostdlib,从而省略了所有标准库的内容。结果是

arm-none-eabi-size --format=berkeley "unaligned.elf"
   text    data     bss     dec     hex filename
    320       0       0     320     140 unaligned.elf
Run Code Online (Sandbox Code Playgroud)

被四等分 然后,我添加了一个char变量,并对其进行了处理:

volatile char c = 0x42;
void Reset_Handler(void) {
    while(1)
        c+=1;
}
Run Code Online (Sandbox Code Playgroud)

导致

Invoking: Cross ARM GNU Print Size
arm-none-eabi-size --format=berkeley "unaligned.elf"
   text    data     bss     dec     hex filename
    336       1       0     337     151 unaligned.elf
Finished building: unaligned.siz
Run Code Online (Sandbox Code Playgroud)

指令对齐到16位。

像STM32系列这样的基于Cortex-M的MCU使用Thumb2指令集,该指令集混合了16位和32位指令。事实证明,我们的第一个程序的长度恰好是四分之一。我添加了一条nop指令

void Reset_Handler(void) {
    asm("nop");
    while(1)
        ;
}
Run Code Online (Sandbox Code Playgroud)

与原始大小相比,大小增加了两个字节:

Invoking: Cross ARM GNU Print Size
arm-none-eabi-size --format=berkeley "unaligned.elf"
   text    data     bss     dec     hex filename
    322       0       0     322     142 unaligned.elf
Finished building: unaligned.siz
Run Code Online (Sandbox Code Playgroud)