本文主要探讨的是MDK开发工具中One ELF Section per Function选项对于代码优化的作用及其实现的机制。

这里以EK-STM32F开发板的LCDDemo实验例程为例进行说明:

1)在MDK的Project -> Options for Target -> Target选项卡下,在Code Generation 中选中Use MicroLIB,选择使用微库。在User选项卡Run User Programs After Build/Rebuild中,勾选Run #1,同时在文本框中输入命令C:/Keil/ARM/BIN31/fromelf.exe --bin -o  ./output/LCDDemo.bin ./output/

LCDDemo_MDK.axf用于生成.bin文件。

2)在选项卡C/C++中选择优化等级2,同时不选中任何的优化选项。保存,编译链接,下载运行程序,查看output中LCDDemo.bin文件的大小为4728Byte。

3)在图3所示的界面中,将One ELF Section per Function选项选中,保存,编译链接,下载运行程序,查看output中LCDDemo.bin文件的大小为3700Byte。

可以从以上的操作看出, 在其他条件相同的情况下,选项One ELF Section per Function可以将LCDDemo最后生成的.bin文件的大小减少1028Byte,这对于存储资源有限的嵌入式设备来说,还是具有很大的吸引力的。

那么,选项One ELF Section per Function是如何对C程序代码进行优化呢?为此,笔者特别设计了一个方案用于验证选项One ELF Section per Function的优化功能。

首先在LCDDemo工程的main.c文件中加入如下的代码:

void unuse()

{

int i,j = 0;

for (i=0; i<0xfffff; i++) j++;

for (j=0; j<0xfffff; j++) i++;

}

unuse()函数仅是为了测试用而加入的一个函数,该函数为被其他任何的函数所调用。下面分别查看使用选项One ELF Section per Function和不使用选项One ELF Section per Function的区别。

A,              如之前的步骤2)所示操作,生成的LCDDemo.bin的大小为7396Byte。同时,笔者采用反汇编过程进一步验证,找到了unuse()的反汇编代码。可以看出,确实因为添加了unuse()这个函数,而使得最后生成的LCDDemo.bin文件的变大。.

B,              如之前的步骤3)所示操作,生成的LCDDemo.bin的大小为3700Byte。同时,笔者采用反汇编过程进一步验证,未找到unuse()的反汇编代码。可以看出,使用选项. One ELF Section per Function后,即使添加了未使用的函数unuse(),也对于最后生成的LCDDemo.bin文件没有任何的影响。

因此,可以得出,选项One ELF Section per Function的主要功能是对冗余函数的优化。通过这个选项,可以在最后生成的二进制文件中将冗余函数排除掉(虽然其所在的文件已经参与了编译链接),以便最大程度地优化最后生成的二进制代码。

而该选项实现的机制是将每一个函数作为一个优化的单元,而并非整个文件作为参与优化的单元。

选项One ELF Section per Function所具有的这种优化功能特别重要,尤其是在对于生成的二进制文件大小有严格要求的场合。人们习惯将一系列接口函数放在一个文件里,然后将其整个包含在工程中,即使这个文件将只有一个函数被用到。这样,最后生成的二进制文件中就有可能包含众多的冗余函数,造成了宝贵存储空间的浪费。

选项One ELF Section per Function对于一个大工程的优化效果尤其突出,有时候甚至可以达到减半的效果。当然,对于小工程或是少有冗余函数的工程来说,其优化效果就没有那么明显了

MDK中One ELF Section per Function选项功能探究【转载】的更多相关文章

  1. keil mdk中如何确保某一段程序不被优化掉(转)

    源:keil mdk中如何确保某一段程序不被优化掉 使用mdk编程,假如有一个有用的函数你定义了但是没有显式的调用,mdk在默认方式下,将会把这个函数从整个程序总删除掉,以节省ROM. 比如,你在RO ...

  2. 在MDK中怎样生成*.bin格式的文件?

    在Realview MDK的集成开发环境中.默认情况下能够生成*.axf格式的调试文件和*.hex格式的可运行文件. 尽管这两个格式的文件很有利于ULINK2仿真器的下载和调试,可是ADS的用户更习惯 ...

  3. 在Ubuntu 16.04 LTS上用g++和gcc编译C/C++代码错误提示“.../x86_64-linux-gnu/crt1.o: ELF section name out of range”

    (有一些图片我是直接从个人的CSDN博客上复制来的) 最近一个多月来,我曾经多次尝试在Ubuntu 16.04 LTS上使用g++和gcc(这俩好像合起来叫MinGW?)来编译C/C++代码,但是在解 ...

  4. arm-none-eabi/bin/ld: build/com.zubax.gnss.elf section `.text' will not fit in region `flash'

    出现如下错误: /arm-none-eabi/bin/ld: build/com.zubax.gnss.elf section `.text' will not fit in region `flas ...

  5. keil MDK中如何生成*.bin格式的文件

    在Realview MDK的集成开发环境中,默认情况下可以生成*.axf格式的调试文件和*.hex格式的可执行文件.虽然这两个格式的文件非常有利于ULINK2仿真器的下载和调试,但是ADS的用户更习惯 ...

  6. Keil MDK中使用pc-lint的详细方法

    keil MDK版本:V4.03 PC-lint版本:  V8.0 关于pc-lint的强大作用,网上有很多,这里不想再复述,只说一句:能通过pc-lint检验的程序不一定没有问题,但通过了pc-li ...

  7. [系统软件]Ubuntu 18.04中的Shutter禁用了“编辑”选项解决

    本文引用自linux公社, 原文请点击 : https://www.linuxidc.com/Linux/2018-04/151911.htm   在Ubuntu 18.04中安装了我最喜欢的截图工具 ...

  8. javascript中的立即执行函数(function(){…})()

    javascript中的立即执行函数(function(){…})() 深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包 ...

  9. 获取AD域中SYSVOL和组策略首选项中的密码

    这种方法是最简单的,因为不需要特殊的“黑客”工具.所有的攻击必须做的是打开Windows资源管理器,并搜索域名为SYSVOL DFS共享的XML文件.在大多数情况下,以下XML文件将包含凭据:grou ...

随机推荐

  1. hdu6055 Regular polygon 脑洞几何 给定n个坐标(x,y)。x,y都是整数,求有多少个正多边形。因为点都是整数点,所以只可能是正四边形。

    /** 题目:hdu6055 Regular polygon 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6055 题意:给定n个坐标(x,y).x,y都 ...

  2. 关于OutputStream的write方法FAQ(from bbs.csdn.net)

    问: Java code ? 1 2 3 4 5 6 7 8 9 10 11 FileInputStream fis = new FileInputStream(new File("C:\\ ...

  3. String类和StringBuffer类

    位于java.lang包中,这个包中的类使用时不用导入 String类一旦初始化就不可以改变,而stringbuffer则可以.它用于封装内容可变的字符串.它可以使用tostring()转换成stri ...

  4. git上解决代码冲突(merge版)

    1.切换到master: git checkout master 2.拉最新代码:git pull origin master 3.切换到提交的分支:git checkout Txxxx 4.合并:g ...

  5. 客户端用JavaScript填充DropDownList控件 服务器端读不到值

    填充没有任何问题,但是在服务器端却取不出来下拉表中的内容.页面代码如下. <form id="form1" runat="server"> < ...

  6. C++ 运算符 [] & *、操作符new 修饰符const inline virtual

    1. [] 这让我想到静态分配内存和动态分配内存,与数据名称无关 局部变量和临时变量会储存在静态缓存区,随着程序运行完而消亡(例如在循环体中定义的局部变量随着循环体结束,局部变量也会消亡). 内存泄漏 ...

  7. NATS源代码分析之auth目录

    NATS是一个轻量的消息发布-订阅系统.NATS的核心是Event machine. 项目Server端源代码地址: github.com/nats-io/gnatsd 在auth目录中, multi ...

  8. 智力大冲浪(洛谷P1230)

    题目描述 小伟报名参加中央电视台的智力大冲浪节目.本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元.先不要太高兴!因为这些钱还不一定都是你的?!接下来主持人宣布了比赛规则: ...

  9. 移动端web页面上滑加载更多功能

    背景介绍: 开发企业微信的一个应用,实现在企业微信中调用自己程序页面,页面加载多模块数据,向下滑加载更多,等等等等,一波三折 然后很早就成功了是这样实现的: html: <div id=&quo ...

  10. ef AddDays报错

    ef func写法,在语句中不能使用adddays方法 )); 这样写就是不行 可以改为: ); 下面是我的一个案例,虽然到了最后都没有实现功能! public List<ContractBud ...