2017-04-18 103 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指令只是一個字節。