Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 通过分解空指针,显著减少编译代码的大小_C_Optimization_Microcontroller_Void Pointers_Code Size - Fatal编程技术网

C 通过分解空指针,显著减少编译代码的大小

C 通过分解空指针,显著减少编译代码的大小,c,optimization,microcontroller,void-pointers,code-size,C,Optimization,Microcontroller,Void Pointers,Code Size,我最近一直在为一个只有2kB闪存的微控制器开发一些C语言的嵌入式软件。编程快结束了,我已经达到了代码极限。到目前为止,当这种情况发生时,我一直在提高编译器的优化水平,重新测试,然后愉快地继续进行。然而,我最近达到了优化的极限,随着最后一点功能的增加,内存再次耗尽。结果,我不得不让乔治·福尔曼(George Foreman)拿出我的源代码,并消耗掉一些脂肪 我到处乱搞,减少了一些抽象层,这稍微有点帮助,但还不够。接下来我看到的是我有了功能原型 void process_event(Event ev

我最近一直在为一个只有2kB闪存的微控制器开发一些C语言的嵌入式软件。编程快结束了,我已经达到了代码极限。到目前为止,当这种情况发生时,我一直在提高编译器的优化水平,重新测试,然后愉快地继续进行。然而,我最近达到了优化的极限,随着最后一点功能的增加,内存再次耗尽。结果,我不得不让乔治·福尔曼(George Foreman)拿出我的源代码,并消耗掉一些脂肪

我到处乱搞,减少了一些抽象层,这稍微有点帮助,但还不够。接下来我看到的是我有了功能原型

void process_event(Event event, void *data);

它将要处理的事件和可用于向调用传递附加数据的空指针作为其参数。如果我不需要任何额外的数据,我将传递
NULL
。这个函数是在开发的早期编写的,我意识到我从来没有使用过
数据
,所以我把它分解了。这一变化使我节省了所需的编译代码大小(~100字节),我想知道为什么,特别是考虑到调用
process\u event
时我通常传递
NULL

大约100个字节可能符合这样一个事实,即每次调用函数时,调用站点都必须传递一个额外的参数-这至少需要清除一个寄存器,并且,取决于您的芯片,在调用之前将其存储在堆栈上


也有可能,每次调用一条指令的简单减少会导致删除更多的代码,具体取决于跳转的实现方式,因为您可能会发现某些代码现在在跳转指令的范围内,使用的是较短的相对偏移量,而不是较长的偏移量。在尝试加载常量时,也可以进行类似的保存

函数被调用了多少次?删除一个参数可以节省多少代码?函数的调用次数相当多(>10次)。这可能很大程度上取决于
事件
,它的大小和结构。您可能遇到了架构的一个边界,在这个边界上,附加的参数对调用约定进行了更改。如果没有
数据
“全部在寄存器中”,则会出现“溢出在堆栈上”或类似的情况。您不会真正指定“可观”在保存字节方面的含义。通过不必在每次调用时将额外的参数推送到堆栈上,您就可以获得一些。此更改节省了大量代码,而不是堆栈或其他运行时存储?你让装配工看看有什么变化了吗?