最近在研究固件升级,在烧写内部FLASH时突然产生一个问题编译出的bin文件一定是4字节的倍数吗?如果不是那么以bin文件总长度除以4的方式写入flash就有可能舍掉了最后的余数。
在stack overflow上得到的答案是:正常情况下编译产生的bin文件是4的倍数,但是并不一定是4字节的倍数,4字节对齐只是因为方便,实际取决于连接脚本等文件的设置。
如果我们打开连接脚本文件(.ld)的话,会看到很多声明如下所示
. = ALIGN(4);
它们指示链接器将当前输出地址提升到可被4整除的值。
举例如下,如果我创建一个空工程,删除以下连接脚本中的align语句
1 ENTRY(Reset_Handler) 2 __stack = 0x20014000; 3 MEMORY 4 { 5 FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K 6 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 80K 7 } 8 SECTIONS 9 { 10 .isr_vector : 11 { 12 . = ALIGN(4); 13 KEEP(*(.isr_vector)) 14 . = ALIGN(4); 15 } >FLASH 16 .text : 17 { 18 *(.text) 19 *(.text*) 20 } >FLASH 21 .rodata : 22 { 23 *(.rodata) 24 *(.rodata*) 25 } >FLASH 26 _sidata = LOADADDR(.data); 27 .data : 28 { 29 _sdata = .; 30 *(.data) 31 *(.data*) 32 _edata = .; 33 } >RAM AT> FLASH 34 .bss : 35 { 36 _sbss = .; 37 *(.bss) 38 *(.bss*) 39 *(COMMON) 40 _ebss = .; 41 } >RAM 42 }
以上连接脚本源程序如下:
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
可以被4整除,然后我在代码中加入一个char型的变量,如下所示:
1 volatile char c = 0x42; 2 void Reset_Handler(void) { 3 while(1) 4 c+=1; 5 }
重新编译连接得到结果是:
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
文件大小不在对4字节对齐。
进一步说明指令是按照16位对齐的。
以Cortex-M作为内核的MCU 如STM32系列使用Thumb2指令集,指令集中的指令有16位也有32位。这导致第一个程序最后是4字节的倍数。当我加入一个 nop指令后
1 void Reset_Handler(void) { 2 asm("nop"); 3 while(1) 4 ; 5 }
编译结果比第一个程序大了两个字节,如下:
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
补充说明:
有人觉得可以把STM32 MCU切换的16位的模式就会得到16位对齐的bin文件。当你真的切换到16位模式确实很可能最后的出的bin文件是2字节的倍数了,但你可能不完全理解这意味着什么。“32位模式”和“16位模式”通常指指针或寄存器大小,而不是指令大小。例如,AMD x64指令集可能被称为“64位模式”,即使其指令长度可变。有些x64指令只有一个字节。
标签:bin,字节,16,text,unaligned,stm32,data From: https://www.cnblogs.com/mangorange/p/17430287.html