1. Linux文件
一个正常可以运行的bin文件,直接进行反汇编以后实际有用的数据行数目*4就是文件ll出来的直接大小数目。一个可执行文件正常包含代码段、只读数据段、读写数据段、未初始化数据段、文件注释五个部分。
代码段(code 或text),代码段由各个函数产生,函数的每一个语句都最终编译成二进制代码。
只读数据段(rodata),被const修饰的初始值非0的全局变量。
读写数据段(data),?.data段包含初始值非0的全局变量(不管静态还是非静态static)
未初始化数据段(bss),包含初始值为0或未初始的全局变量(不管有没有const修饰也不管是不是静态还是非静态)
文件注释(comment),主要是文件变量和文件相关的说明,这部分不计入实际bin文件大小的。
另外,局部变量则保存在栈中,它的生存周期仅在所在局部(即所定义的{}内)
#include <stdio.h>
#include <string.h>
#define N 10
int a_global;
int a1_global=0;
int a2_global=5;
static int b_global;
static int b1_global=0;
static int b2_global=6;
const int c_global;
const static int c1_global;
const static int c2_global=7;
int main()
{
const char c_local;
const char c1_local='A';
return 0;
}
asm.elf: file format elf32-littlearm
Disassembly of section .text:
00000000 <main>:
0: e1a0c00d mov ip, sp
4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
8: e24cb004 sub fp, ip, #4 ; 0x4
c: e24dd004 sub sp, sp, #4 ; 0x4
10: e3a03041 mov r3, #65 ; 0x41
14: e54b300e strb r3, [fp, #-14]
18: e3a03000 mov r3, #0 ; 0x0
1c: e1a00003 mov r0, r3
20: e89da808 ldmia sp, {r3, fp, sp, pc}
Disassembly of section .data:
00000800 <__data_start>:
800: 00000005 andeq r0, r0, r5
00000804 <b2_global>:
804: 00000006 andeq r0, r0, r6
Disassembly of section .rodata:
00000024 <c2_global>:
24: 00000007 andeq r0, r0, r7
Disassembly of section .bss:
00000808 <a1_global>:
808: 00000000 andeq r0, r0, r0
0000080c <b1_global>:
80c: 00000000 andeq r0, r0, r0
00000810 <b_global>:
810: 00000000 andeq r0, r0, r0
00000814 <c1_global>:
814: 00000000 andeq r0, r0, r0
00000818 <c_global>:
818: 00000000 andeq r0, r0, r0
0000081c <a_global>:
81c: 00000000 andeq r0, r0, r0
Disassembly of section .comment:
00000000 <.comment>:
0: 43434700 cmpmi r3, #0 ; 0x0
4: 4728203a undefined
8: 2029554e eorcs r5, r9, lr, asr #10
c: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1}
10: Address 0x10 is out of bounds.
2. 程序运行
堆(heap)?:堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc/free等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张)/释放的内存从堆中被剔除(堆被缩减)
栈(stack)?:栈又称堆栈, 存放程序的?局部变量?(但不包括static声明的变量,?static?意味着?在数据段中?存放变量)。除此以外,在函数被调用时,栈用来传递参数和返回值。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。储动态内存分配,需要程序员手工分配,手工释放
如果程序是裸机驱动开发,程序是通过下载工具加载到单板的flash上面,不像系统编程本身编写链接出来的文件就是在系统管理的flash空间中。在嵌入式中,文件组成格式和加载格式是一致,只是偏移地址不一样。程序运行中逻辑程序最大的一个问题是代码的重定位,设计复杂的代码重定位流程。但是实际系统文件运行时,由系统加载文件到SDRAM中,一般也不需要复杂的代码重定位处理流程。
|