C51和M3的while语句效率分析

来源:本站
导读:目前正在解读《C51和M3的while语句效率分析》的相关信息,《C51和M3的while语句效率分析》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《C51和M3的while语句效率分析》的详细说明。
简介:通过程序举例的方式详细介绍了C51和M3的while语句效率分析

#include"stdint.h"

uint8_t while_inc(uint8_t ch)

{

uint8_t i = 0;

do

{

ch ++;

}while (++i < 8);

return ch;

}

#include"stdint.h"

uint8_twhile_dec(uint8_t ch)

{

uint8_t i = 0;/*不产生汇编代码*/

i = 8;

do

{

ch ++;

} while (--i);

return ch;

}

代码-1用“++”判断的while代码段

代码-2用“--”判断的while代码段

上面两段示例代码中,循环次数都一样,但是在有些平台中,时空效率却大不相同。以51架构单片机为例,我们来分析它编译出来的汇编代码。

; FUNCTION _while_inc

;---- Variable 'ch' assigned to Register 'R7' ---- /*用R7表示形参ch */

;---- Variable 'i' assigned to Register 'R6' ----/*用R6表示局部变量i*/

0000 E4 CLR A /* i = 0; */

0001 FE MOV R6,A

0002 ?C0003:

0002 0F INC R7 /* ch++ */

;代码“while (++i < 8)”对应汇编语句

0003 0E INC R6

0004 EE MOV A, R6

0005 C3 CLR C

0006 9408 SUBB A, #08H

0008 40F8 JC ?C0003

000A ?C0004:

000A 22 RET

代码-3C51平台“++”编译得到的汇编代码段(C51平台)

; FUNCTION _while_dec

;---- /*用R7表示形参ch 用R6表示局部变量i */

0000 E4 CLR A /* uint8_t i = 0令人困惑?? */

00017E08 MOV R6,#08H/* i = 8; */

0003 ?C0003:

0003 0F INC R7 /* ch++ */

;代码“while (--i)”对应汇编语句

0004 DEFD DJNZ R6,?C0003

0006 ?C0004:

0006 22 RET

代码-4C51平台“--”编译得到的汇编代码段(C51平台)

从上述的汇编代码中,我们发现用“++”和“--”的两段while循环代码,在空间上前者比后者多了4条指令共5个字节,时间上多花费了8次*4=32个指令周期,如果循环次数进一步加大,这一差距就不能忽视。

为何会有如此之多的差异?其本质原因是因为C51拥有一条“复合指令DJNZ”,其定义如下,意为:将“寄存器或者某个ram内的byte变量”的值减1,完事后判断不为0则跳转”。该指令融合了“算术运算 + 逻辑运算 + 跳转”三个功能。

所以,你该知道,大牛的代码while用"--和0比较",一般的代码就是“++和var比较”或者用“for循环”。

一般来说,不管什么平台,判断0总是效率较高的,毕竟cpu的状态寄存器都有个Zero状态位。

------------------------------------------------------------------------------------------------------------------------------------------------

而对于M3平台,两段代码并没有带来明显的时空差异。

while_inc PROC

MOVS r1,#0

|L1.2|

ADDS r0,r0,#1

ADDS r1,r1,#1

UXTB r1,r1

UXTB r0,r0

CMP r1,#8

BCC |L1.2|

BX lr

ENDP

while_dec PROC

MOVS r1,#8

|L1.2|

ADDS r0,r0,#1

SUBS r1,r1,#1

UXTB r0,r0

ANDS r1,r1,#0xff

BNE |L1.2|

BX lr

ENDP

M3平台“++”的汇编代码段(M3平台)

M3平台“--”的汇编代码段(M3平台)

这两段汇编,前者之所以比后者多了一句“UXTB r1,r1”,因为加法的值需要32位和8位的数值转换,归零的减法不需要。这又应那个原则:“零值”操作效率较高。

因此,一个软件工程师,需要对其操作平台的指令系统有足够的熟悉,对基本C语句的汇编转换了然于心,才能写出高质、高效的代码。老工程师的价值,也体现在此。

另外值得一提的是,在这个实验中我发现一个比较有意思的现象:在函数while_dec中变量声明兼初始化代码“uint8_t i = 0;”,紧随其后就是“i = 8”的覆盖赋值代码。而它在C51平台编译器上,却产生了一个冗余代码“CLR A”,令人困惑。在M3平台的编译中,就没有这样的现象了。不管怎样,随着编译器越来越智能,变量声明时即刻初始化,是一个非常好的编程习惯,它不会对代码空间增加额外的负担。

提醒:《C51和M3的while语句效率分析》最后刷新时间 2024-03-14 01:01:53,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《C51和M3的while语句效率分析》该内容的真实性请自行鉴别。