欢迎来到天天文库
浏览记录
ID:4160420
大小:590.20 KB
页数:8页
时间:2017-11-29
《mcu编译与运行浅谈》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、MCU编译与运行浅谈学电子的人都知道:使用C语言编写代码后,我们必须将其处理成机器码,才能使之在MCU中执行,这其中的步骤基本概括为“编译->汇编->链接->加载->启动”。编译和汇编很容易理解,不是我想讲解的重点,这里主要讲“链接->加载->启动”三部分,我会尽量使用浅显的文字进行概括性阐述。很多电子工程师做了半辈子MCU可能还不能完全理解这三部分,不是说这些工程师们脑残,而是即使他们不搞懂这些也不影响他们做出好的设计,而且真正走上工作岗位后很少有机会像在大学期间有大把大把的时间去系统的学习知识了,企业里的设
2、计讲究团队合作,很多电子工程师仅仅精通某一方面。我现在所在的公司里有很多SOC设计的高手,但相当一部分人并不是很清楚ARM体系架构与启动流程方面的知识。因此,我希望实验室内的学生可以常思考、相互交流心得,尽量在大学阶段打扎实基础,搞定每个细节,往往越细微以及容易忽视的知识点理解起来也越难。一、编译和汇编我们知道C代码经过编译、汇编的过程后可以得到目标文件,比较常用的编译/汇编器为Cx51、icc、gcc、armcc/armasm等。以ARM为例,我们一般使用armcc/armasm,它的编译效率以及代码的执行效
3、率大大高于gcc,但很遗憾的是armcc/armasm是收费软件,如ADS、MDK、RVDS等都是使用的armcc/armasm,IARforARM使用的是自己设计的编译/汇编器,有兴趣的可以自己去网上查找相关信息。armcc对应命令行代码简略写为(以S3C6410为例):armcc:armcc--debug--cpu=ARM1176JZF-Sarmasm:armasm--debug--keep--cpu=ARM1176JZF-S但是我们的工程一般都有很多c文件以及s文件,它们每个都会对应生成一个o文件(目标文
4、件)(注意,如果说h文件没有实体定义就不会生成o文件,但如果h文件中有函数定义,那么目标文件就会很乱,因此我们一般遵守“h文件声明、c文件定义”的规则,也就即“函数定义写在c文件中,函数声明写在h文件中”,这也证明了对于一个函数“可以多次声明,但不可以多次定义”,比如对于一个h文件,我们可以不关注它是否被重复包含,但如果你想include一个c文件,就一定要看清楚这个c文件有没有被别的文件也包含了,否则的话就会出现“重复定义”错误)。那么链接的目的就是要把编译、汇编得到的目标文件合并成可执行程序,当然这里所说的
5、目标文件也包括库文件以及一些命令行参数,如下图所示:二、合并(链接)和加载流程链接器是对每一个程序的各个段进行绑定并分配相对地址,而加载器完成最后的重定位步骤并赋予实际地址。再通俗一点讲就是:编译器和汇编器通常为每个目标文件创建程序地址从0开始的目标代码,如果一个程序是由多个子程序组成的,那么所有的子程序必须被加载到互不重叠的地址上;链接器将多个子程序构建成一个程序,并生成一个链接好的起始地址为0的输出程序,各个子程序通过重定位在大程序中确定位置;当这个程序被加载时,系统会选择一个加载地址,而连接好的程序会作为
6、整体被重定位到加载地址。每个输入文件都包含一系列的段(segments),即会被连续存放在输出文件中的代码或数据块。一个ARM程序(指正在执行的程序,而非保存在ROM中的bin映像(image)文件)包含3部分:RO,RW和ZI,,但ARM映像文件只包含了RO和RW数据,这是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可:1、RO是程序中的指令和常量;2、RW是程序中的已初始化变量;3、ZI是程序中的未初始化的变量。一般在汇编文件中可以看到,下例说明:AREA是指定区域的关键字
7、,INITARM1136为段名,而且是RO类型的(PRESERVE8指令用于指定当前文件保持堆栈八字节对齐):每一个输入文件至少还包含一个符号表(symboltable),一般由链接器定义,在当前文件中定义并在其他文件中使用,这也使得可以通过这些符号方便的进行目标文件的重组,如(region_nane代表某个段,在下面的scatter文件中会涉及):Load$$region_nane$$Base代表region_nane(段名)加载时的起始地址Image$$region_nane$$Base代表region_n
8、ane运行时的起始地址Image$$region_nane$$Length代表region_nane运行时的长度现在的链接器一般会进行两遍扫描,首先对输入文件进行扫描,得到各个段的大小,并收集对所有符号的定义和引用,创建一个含有所有段的段表,和包含所有符号的符号表。利用第一遍扫描得到的数据,链接器可以为符号分配数字地址,决定各个段在输出地址空间中的大小和位置,并确定每一部分在输出文件中
此文档下载收益归作者所有