2017-04-18 81 views
2

我正在编程像STM32F4 **和STM32F0 **的MCU,使用ARM GCC非可编译器,c/C++并且发现了有趣的模式。ARM二进制大小

如果我建立一些* .bin文件,它的大小始终是整除4

我想可能是因为MCU是32位(= 4字节)。所以bin_size%4 == 0。我尝试了一些“黑客”;例如将一些字节数组扩大1,但二进制大小总是相同的。当我放大数组时,二进制大小变大,但又可以被4整除。

我可以把这个效果看成公理吗?

或者当这种情况不起作用时会出现某种情况吗?例如,是否有可能以某种方式将32位STM32 MCU切换到16位模式?或者可以用另一个编译器创建4个不可分的二进制文件?

+3

为什么地球上你想要二进制的大小不是4的倍数? –

+2

这里你的目标是什么?编译器可能会填充您的结构以确保内存访问清晰。如果你想要突破这个问题,我不知道你希望达到什么目的。 – tadman

+1

打开文件,字节添加到末尾,关闭它,你可以有一个奇怪的长文件,那么怎么看的工具很多突破,当您尝试使用它... –

回答

4

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

对齐在链接描述文件中强制执行。如果您在*.ld文件的项目看,你会发现有很多的

. = ALIGN(4); 

语句。他们命令链接器将当前的输出地址到所以我已经创建了一个空的项目由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 
} 

最小的程序:

void Reset_Handler(void) { 
    while(1) 
     ; 
} 

编译和链接-nostartfiles -nodefaultlibs -nostdlib它,离开了所有的标准库的东西。结果是

arm-none-eabi-size --format=berkeley "unaligned.elf" 
    text data  bss  dec  hex filename 
    320  0  0  320  140 unaligned.elf 

被四等分整除。然后,我添加了一个char变量,并做了一些与它:

volatile char c = 0x42; 
void Reset_Handler(void) { 
    while(1) 
     c+=1; 
} 

这就造成了

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 

指令对齐到16位。

像STM32系列这样基于Cortex-M的MCU使用Thumb2指令集,它是16位和32位指令的混合。事实证明,我们的第一个程序恰好有一个可以被四整除的长度。我已经添加单个nop指令

void Reset_Handler(void) { 
    asm("nop"); 
    while(1) 
     ; 
} 

和尺寸增加了两个字节,比原来的:

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 
+0

大,你的回答完全覆盖我需要的所有问题知道! 我让我开了* .LD文件有。 =每个部分中的ALIGN(4)。所以,这可能是原因,我的二进制文件的大小总是整除4. 我问,因为我有我自己的引导程序具有闪烁新的二进制文件,以MCU能力,我认为规则“被4整除”作为规则的一个其中必须有新的二进制通过,以及CRC校验等。现在我知道这并不容易。 –

0

“。例如,是否有可能以某种方式切换32位STM32 MCU到16位模式“

There is 16位模式,但你可能不完全明白这是什么意思。要谷歌它,你会搜索“ARM拇指”。这可能会导致* bin文件是2个字节的倍数。然而,“32位模式”和“16位模式”通常指的是指针或寄存器大小,而不是指令大小,例如, AMD x64指令集可能被称为“64位模式”,即使其指令是可变长度的。一些x64指令只是一个字节。