开发环境:

 

 

工具集:

这些工具集是为了配合GCC编译器进行高效开发而设计的。

 

实验:

test.c:

func.c:

g_pointer默认为空指针。

使用addr2line定位错误:

开启core dump选项就是为了记录程序崩溃的最后一刻程序的状态和寄存器的状态。

 

 

 

 

 成功定位到了出错的地方。

 

 剔除调试信息:

 

示例:

 

 剔除调试信息后程序变小了,但是这时候没有了调试信息,也就不能有addr2line定位bug了:

 

 

 

ar:

 

将x.o y.o打包进libname.a中。

ar的x选项可以将.a解压。

实验:

在链接是有时候我们不想链接.a文件中的所有内容,这时候我们就可以将.a解压出来,找出需要的.o文件,然后链接那个.o就可以了。

 

nm:

 

 

实验:

使用nm查看符号:

 

 func前面的T代表代码段,00000000表示func的地址相对于代码段的起始偏移。

 g_pointer前面的C代表不知道这个变量位于哪个段,前面的00000004表示g_pointer的大小。

g_global在bss段,且相对于bss段的起始偏移为00000000。

g_test在data段,且相对于data段的起始偏移为00000000。

 链接生成可执行文件,再次nm查看:

 

 

运行输出的结果:

运行结果和nm查看的结果相同。

 

objdump:

objdump -d可以得到目标文件对应的汇编代码。

示例:

 

 

objdump -S可以查看汇编到源程序之间的映射:

 

 

*g_pointer那一行对应的汇编就是它下面的那三行汇编。

 

objdump -h可以查看目标文件中的详细的段信息。

 

 

objdump -h输出表格的列说明:

 

对可执行文件执行objdump -h:

 

VMA和LMA是一样的。

LMA指的是什么呢?

可执行程序的加载:

在桌面环境下,加载程序的过程如下:

1、创建进程,分配虚存空间

2、将可执行文件中的段拷贝到内存中,拷贝时需要用到可执行文件中的段的信息,这些信息就在文件里面。file off表示相应的段在文件中的偏移。

  根据段的VMA拷贝到虚拟内存相应的VMA地址上。编译的时候会给出每个段的虚拟起始地址VMA。这个虚地址就代表了加载的目标地址。

  桌面环境中VMA等于LMA。LMA就是加载地址,指的是终点。

  运行地址指的是实地址。

 

嵌入式环境nand:

nandflash只能存储,不能执行程序。

上电时文件系统不存在,需要从一个固定的地址读取到ram中。

这个地址叫做加载地址,这个地址在这里指的是起点。

这时VMA就不等于LMA,LMA指的是段在flash中的地址,是起始地址。

运行地址是代码在ram中执行的地址,是实地址。

 

嵌入式环境NOR:

nor flash可以直接执行程序。

可执行文件烧写到nor中,上电后直接在nor执行。

这时的加载地址和运行地址都是nor中的地址,这时加载地址就是运行地址,这种情况下可能没有虚存地址。

 

其他工具:

演示:

 

size查看各个段的大小,可以有目的的对每个段进行优化。

 

参考:狄泰软件学院视频教程

 

posted on 2018-10-21 22:24  周伯通789  阅读(294)  评论(0编辑  收藏  举报