C51和M3的while语句效率分析
单片机吧
全部回复
仅看楼主
吧务
level 14
MCU起航 楼主
上面两段示例代码中,循环次数都一样,但是在有些平台中,时空效率却大不相同。以51架构单片机为例,我们来分析它编译出来的汇编代码。
从上述的汇编代码中,我们发现用“++”和“--”的两段while循环代码,在空间上前者比后者多了4条指令共5个字节,时间上多花费了8次*4=32个指令周期,如果循环次数进一步加大,这一差距就不能忽视。
为何会有如此之多的差异?其本质原因是因为C51拥有一条“复合指令DJNZ”,其定义如下,意为:将“寄存器或者某个ram内的byte变量”的值减1,完事后判断不为0则跳转”。该指令融合了“算术运算 + 逻辑运算 + 跳转”三个功能。
所以,你该知道,大牛的代码while用"--和0比较",一般的代码就是“++和var比较”或者用“for循环”。
一般来说,不管什么平台,判断0总是效率较高的,毕竟cpu的状态寄存器都有个Zero状态位。
---------------------------------------------------------------------
而对于M3平台,两段代码并没有带来明显的时空差异。
这两段汇编,前者之所以比后者多了一句“UXTB r1,r1”,因为加法的值需要32位和8位的数值转换,归零的减法不需要。这又应那个原则:“零值”操作效率较高。
因此,一个软件工程师,需要对其操作平台的指令系统有足够的熟悉,对基本C语句的汇编转换了然于心,才能写出高质、高效的代码。老工程师的价值,也体现在此。
另外值得一提的是,在这个实验中我发现一个比较有意思的现象:在函数while_dec中变量声明兼初始化代码“uint8_t i = 0;”,紧随其后就是“i = 8”的覆盖赋值代码。而它在C51平台编译器上,却产生了一个冗余代码“CLR A”,令人困惑。在M3平台的编译中,就没有这样的现象了。不管怎样,随着编译器越来越智能,变量声明时即刻初始化,是一个非常好的编程习惯,它不会对代码空间增加额外的负担。
2020年04月23日 06点04分 1
1