计算C文件的代码部分的大小

时间:2014-04-17 22:00:21

标签: c assembly flash-memory

参考此:
calculating FLASH utilisation by C code

我决定检查实际装配说明的计算 所以我的脚本计算汇编指令,位于功能启用代码的汇编列表文件中 e.g。

if(TRUE == feature1_enable)
{
    // instruction counting starts here
    doSomething;
    .
    .
    .
    // instruction counting stops here
}

这给了我一些计数x,我可以从中找出代码的大小。

要交叉检查结果,我决定nm功能代码的目标文件,但nm给出整个功能的大小,而不是单个语句。
所以我在单独的文件中复制了该功能的代码部分,制作了它的功能,包括必要的头文件和声明的变量来获得这个文件的编译(通过照顾本地人将保持本地和全局仍然是全局的)。 所以新文件看起来像这样:

#include "header1.h"
#include "header2.h"

global_variables;
void checkSize( void )
{
    local_variables;

    // feature1_enable code
    doSomething;
    .
    .
    .
 }

现在函数checkSize只包含功能启用代码,因此在编译之后,如果我nm obj文件,我应该能够获得与程序集计数几乎相同的结果(除了一些额外的大小)由功能设置使用)。 但事实并非如此,我收到了巨大的差异。 (在汇编指令的情况下为1335个字节,在obj文件的nm的情况下为1458个字节)。
为了进一步说明,我使用函数checkSize创建了文件的程序集,并与原始程序集文件进行了比较。 我知道由于添加了checkSize函数,还有一些额外的东西,但功能启用代码的指令应该是相同的(使用相同的编译器优化和其他选项)。
但他们不一样。

现在的问题是,为什么大功能内的功能代码的汇编指令存在差异,以及当我仅使用功能代码将其移动到另一个文件时。 在任何一种情况下都有什么可以预测额外的尺寸吗?

2 个答案:

答案 0 :(得分:1)

这里可能会发生一些事情。确保您必须阅读实际的汇编代码并弄清楚它在做什么。将它设置为高优化级别时,编译器非常聪明。例如,在您的第一个代码段中,编译器很可能将汇编语句放在

之外
// instruction counting starts here
// instruction counting stops here

在评论之间执行工作的评论。在您的第二个示例中,无法进行优化,并且需要在函数中完成所有工作。另外不要打算prolog和epilog函数占用的空间量。根据处理器的指令集及其堆栈和寄存器的使用情况,它可能非常大。例如,在Power PC上没有多个寄存器指令,你必须按下每个单独的寄存器,并在进入和离开函数时将每个寄存器从堆栈帧中弹出。当你处理32个寄存器时,可能会有相当多的代码。

当您为编译器设置了高优化级别时,您可以尝试一种技巧。编译器不能跨“asm”语句进行优化,因为它不知道它们中发生了什么。你可以做的是在“asm”语句中加入一些虚拟代码。我个人喜欢创建目标文件中的全局符号。这样我就可以获得起始符号和结束符号的地址,并计算其间的代码大小。它看起来像这样......

asm(" .globl sizeCalc_start");
asm(" sizeCalc_start: ");
// some code
asm(" .globl sizeCalc_end");
asm(" sizeCalc_end:");

然后你可以在像

这样的函数中做点什么
extern int sizeCalc_start;
extern int sizeCalc_end;
printf("Code Segment Size %d\r\n", &sizeCalc_end - &sizeCalc_start);

我过去做过这个并且有效。没有尝试编译这个dunno你可能需要搞砸一点才能得到你想要的东西。

答案 1 :(得分:0)

优化很棘手。在一个大函数(和大文件)中,编译器具有更广泛的上下文,并且可以更积极地进行优化 - 重用常用表达式,选择较短形式的分支等(在不知道目标体系结构的情况下很难确切地说)。

PS:我不太确定你如何从汇编计数到字节数。