数码之家

 找回密码
 立即注册
搜索
查看: 4226|回复: 17

有没有人大概统计过代码输出二进制文件的比例关系

[复制链接]
发表于 2021-8-26 15:52:15 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
按自己的经验,正常的应用或者协议,用c,300-400行差不多输出1k大小,也就是说8k flash可以写个3000行代码。
当然这只是估计,跟不同种类的代码有很大关系,平台是ARM M0
发表于 2021-8-26 17:39:49 | 显示全部楼层
这个可不好说,有些库函数内部一大堆复杂操作,你可能随便调几个功能接口总代码量立马就上去好多了。
回复 支持 反对

使用道具 举报

发表于 2021-8-26 17:40:30 | 显示全部楼层
和内核,编译器,软件写法,都有直接关系
回复 支持 1 反对 0

使用道具 举报

发表于 2021-8-26 18:18:40 | 显示全部楼层
开玩笑,这还能这么算的么
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-26 18:39:56 | 显示全部楼层
la45088d1 发表于 2021-8-26 17:39
这个可不好说,有些库函数内部一大堆复杂操作,你可能随便调几个功能接口总代码量立马就上去好多了。 ...

当然不能算库,只算源码
回复 支持 反对

使用道具 举报

发表于 2021-8-26 18:55:24 | 显示全部楼层
没有这样说法的,看代码和单片机架构的。

:titter:

有效代码400行出1k二进制,你都写的什么啊。 :praise:

给 CPU寄存器赋值也要 2 字节以上,内存变量还得往上,

以一个简单的IO组清0为例:

GPIOA->ODR=0;

转为汇编代码的话,可能是:



  1. 48000000
  2. MOVS r0,#0
  3. LDR r1,XXXXXXXX
  4. STR r0,[r1,#14]
复制代码
注:以上汇编手打,不一定全对,有错请高手指点


这里就需要 4+2+2+2=10字节啦。
实际项目的代码肯定比这种复杂。


回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-26 19:01:46 | 显示全部楼层
junyee 发表于 2021-8-26 18:55
没有这样说法的,看代码和单片机架构的。

可以看统计规律,比如做了20个项目,把每个项目代码量和二进制大小对比一下,比例大概就差不多了

当然每个项目最好是以万行、几十k来计算,拿个几百行的没什么说服力
回复 支持 反对

使用道具 举报

发表于 2021-8-26 20:37:46 | 显示全部楼层
本帖最后由 junyee 于 2021-8-26 20:40 编辑
fan.lu 发表于 2021-8-26 19:01
可以看统计规律,比如做了20个项目,把每个项目代码量和二进制大小对比一下,比例大概就差不多了

当然每 ...

我拿个比较简单常用的代码,一行C出来 10字节的汇编指令。


你要是把注释,换行,括号 什么算上去,当我没说。

这是我几年前一个点屏的工程,外设初始化用了hal库。



统计参与编译的代码,2804 其中已经包含空行,注释,函数的大括号。
生成的代码已经有 14kb.



  1. findstr ";;;" *.txt >all.c

  2. 然后用正则工具替换掉注释,空行。
复制代码

走了,不在这浪费时间了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2021-8-26 23:46:27 来自手机浏览器 | 显示全部楼层
说简单点的,DS18B20温度转成十进制,带小数点计算的比不带的多100个字节。
回复 支持 反对

使用道具 举报

发表于 2021-8-27 09:08:24 | 显示全部楼层
本帖最后由 junyee 于 2021-8-27 09:13 编辑
zj97czb 发表于 2021-8-26 23:46
说简单点的,DS18B20温度转成十进制,带小数点计算的比不带的多100个字节。

可以使用带浮点的MCU啊。:lol:
~~~
stm32 cm0/cm3 中大部分指令是双字节的,
一个指令能干的事不多,除非寄存器在上文中有有效值。
不做逻辑判断循环,一句简单的赋值c代码 需要 2条指令,如果赋值是2/4byte 还需要额外的rom空间索引。

简单的翻转IO代码,不使用库了,大家猜猜生成的代码是多大。
  1. int main(void)
  2. {
  3.   RCC->AHBENR |= 0x00020000;
  4.   GPIOA->MODER = 0x00000001;
  5.   GPIOA->OTYPER = 0x00000001 ;
  6.   GPIOA->OSPEEDR = 0x00000001 ;
  7.   while(1){
  8.     GPIOA->BSRR = 0x1 ;
  9.     GPIOA->BSRR = 0x1<<16 ;        
  10.   }        
  11. }
复制代码
Program Size: Code=1300 RO-data=212 RW-data=20 ZI-data=1636  

查看 Project.map 文件可以知道 main函数 11 (括号不算或写成js形式8行)行C代码 占用了 48+8 字节的空间。  。
只要是正常的代码不是神优化,c有效行与最终的rom大小比要远大于4.

如果再按楼上兄弟说的,在main头部做个小数运算,那就不得了了(cm0没有浮点计算指令)


  1. int main(void)
  2. {
  3.   volatile  double a=3.1415926;
  4.   a*=2;
  5.   RCC->AHBENR |= 0x00020000;
  6.   GPIOA->MODER = 0x00000001;
  7.   GPIOA->OTYPER = 0x00000001 ;
  8.   GPIOA->OSPEEDR = 0x00000001 ;
  9.   while(1){
  10.     GPIOA->BSRR = 0x1 ;
  11.     GPIOA->BSRR = 0x1<<16 ;        
  12.   }        
  13. }
复制代码


Program Size: Code=1916 RO-data=212 RW-data=20 ZI-data=1636  


打脸打嘴:shutup:,忍不住又跟贴了。

回复 支持 反对

使用道具 举报

发表于 2021-8-27 10:13:41 | 显示全部楼层
用C代码的行数来计算编译输出量??长见识了。。。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-27 10:31:09 | 显示全部楼层
junyee 发表于 2021-8-26 20:37
我拿个比较简单常用的代码,一行C出来 10字节的汇编指令。

用了库就要把库的那一部分也算进来;否则别人写得很好的一个功能,只需一个外部接口,你调一行代码就声称多少k的bin,岂不是有点偷奸耍滑?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-27 10:35:24 | 显示全部楼层
junyee 发表于 2021-8-27 09:08
可以使用带浮点的MCU啊。
~~~
stm32 cm0/cm3 中大部分指令是双字节的,

前面的main里每个都有赋值,所以代码大了些,也就50几字节,比11行也没有远大于4吧!
回复 支持 反对

使用道具 举报

发表于 2021-8-27 12:16:21 | 显示全部楼层
fan.lu 发表于 2021-8-27 10:35
前面的main里每个都有赋值,所以代码大了些,也就50几字节,比11行也没有远大于4吧! ...

现在很少人这样直接用寄存器写了,所以会远大于4.如果你能写出 比这个更简单的.c 且让keil能出现神优化生成bin大小与行数比小于4的,欢迎你献出代码来使劲喷我。

而且我可以写成js样式:
  1. int main(void){
  2.   RCC->AHBENR |= 0x00020000;
  3.   GPIOA->MODER = 0x00000001;
  4.   GPIOA->OTYPER = 0x00000001 ;
  5.   GPIOA->OSPEEDR = 0x00000001 ;
  6.   while(1){
  7.     GPIOA->BSRR = 0x1 ;
  8.     GPIOA->BSRR = 0x1<<16 ;        } }
复制代码


你以为 一堆的 0x00000001 会占用大量空间?
敢情卖大几万块一年的编译器这么傻吗?
0x00000001  会变成#1.,而且4,5行会搬用第3行的取值。

有没有投机取巧,代码已经给你了。你可以自己建个工程试一试。
浮点库是是keil 自带他默认调用的,关我什么事?
第二例只是演示在不带浮点运算的M0中进行浮点运算会占用大量空间。

`volatile  double a=3.1415926;`  16字节。
`a*=2;`    16字节,另外还调用了 _dmul 库。


最后科普一下





把这个勾上,就能看到编译后的汇编代码。





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

打赏

参与人数 1家元 +20 收起 理由
杨雪飞 + 20 虽然没懂,但是看着好像很有道理.

查看全部打赏

回复 支持 反对

使用道具 举报

发表于 2021-8-27 12:36:09 | 显示全部楼层
几行代码不服,非要上千行代码 :giggle:



  1. int main(void)
  2. {
  3.   volatile uint16_t a=0;
  4.   a++;
  5.   a++;
  6.   //...重复1000行
  7.   a++;
  8. }
  9.   
  10.       
复制代码


有兴趣的朋友测试下:

Program Size: Code=11252 RO-data=212 RW-data=20 ZI-data=1636  
回复 支持 反对

使用道具 举报

发表于 2021-8-27 12:51:09 | 显示全部楼层
本帖最后由 junyee 于 2021-8-27 12:54 编辑

说了这么多,也着实浪费不了少时间。
我的观点是,c代码和生成了字节没有一个确定的关系,根据不同平台,编译器,码猿水平,风格 都有关系。

空行,注释和函数大括号 不生成实际代码 。

同一句c代码有可能被编译器优化掉,
大多数的情况生成2条以上指令,有些时间编译器会根据上下文优化,论平均值肯定超2条。

业余爱好者,一个工程纯手打的代码也就几百到一两千行也就差不多了。
毕竟有些库是可以直接复制过来的,无论是别人开源的还是自己以前写的,没必要再打一遍。

现在的arm cm0/3/4 这些单片机有较大的存储空间,其实没必要究结代码占多少空间。
至少,c语言的浪费比现代的编程语言可要好太多了。



回复 支持 反对

使用道具 举报

发表于 2021-8-27 14:51:52 | 显示全部楼层
arm的流水线结构,同一条机器指令,不同时候执行的时间都无法精确算出来
回复 支持 反对

使用道具 举报

发表于 2021-8-27 15:43:53 | 显示全部楼层
junyee 发表于 2021-8-27 12:51
说了这么多,也着实浪费不了少时间。
我的观点是,c代码和生成了字节没有一个确定的关系,根据不同平台,编 ...

项目之初要估算Flash的使用量,好选择合适容量的MCU
所以凭经验估算flash的使用量还是有用的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-6-7 01:13 , Processed in 0.156000 second(s), 13 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表