历史上的今天
返回首页

历史上的今天

今天是:2025年06月17日(星期二)

正在发生

2021年06月17日 | C51优化设计之使用DJNZ循环指令提高执行效率

2021-06-17 来源:eefocus

C51有三种循环语句即while,do-while和for,这三种循环都可以用来处理同一问题,基本上三者可以相互替换.但由于C51是针对51汇编语言的编译器,如果不注意51汇编指令的特点,不同的编程方式可能得到不同的程序性能(执行速度和代码长度).以计算1+2+3+...+9+10为例,下面做一对比.


程序1:

unsigned char i;

unsigned char sum;

for(i=1,sum=0;i<11;i++)

{

sum+=i;

}

汇编代码为:

C:0x0003 7F01 MOV R7,#0x01

C:0x0005 E4 CLR A

C:0x0006 FE MOV R6,A

C:0x0007 EF MOV A,R7

C:0x0008 2E ADD A,R6

C:0x0009 FE MOV R6,A

C:0x000A 0F INC R7

C:0x000B BF0BF9 CJNE R7,#0x0B,C:0007

代码长度(字节):11,执行周期(机器周期):63


程序2:

unsigned char i;

unsigned char sum;

for(i=10,sum=0;i;i--)

{

sum+=i;

}

汇编代码为:

C:0x000F 7F0A MOV R7,#0x0A

C:0x0011 E4 CLR A

C:0x0012 FE MOV R6,A

C:0x0013 EF MOV A,R7

C:0x0014 2E ADD A,R6

C:0x0015 FE MOV R6,A

C:0x0016 DFFB DJNZ R7,C:0013

代码长度(字节):9,执行周期(机器周期):53


程序3:

unsigned char i=11;

unsigned char sum=0;

while(i--)

{

sum+=i;

}

汇编代码为:

C:0x0003 7F0A MOV R7,#0x0B

C:0x0005 E4 CLR A

C:0x0006 FE MOV R6,A

C:0x0007 AD07 MOV R5,0x07

C:0x0009 1F DEC R7

C:0x000A ED MOV A,R5

C:0x000B 6005 JZ C:0012

C:0x000D EF MOV A,R7

C:0x000E 2E ADD A,R6

C:0x000F FE MOV R6,A

C:0x0010 80F5 SJMP C:0007

代码长度(字节):15,执行周期(机器周期):130


从以上三个不同程序可以看出,其运算结果都是0x37(55),但最短代码为9,最长代码为15,最快速度为53,最慢速度为130,可见三个程序的性能差异较大.


如何编出占用空间小运行效率高的循环代码呢?在C51编译环境下要写出优秀的循环代码必须熟悉51汇编语言的指令系统.观察程序2,循环控制指令使用了DJNZ循环转移指令,该指令同时完成计数和循环判断两种操作,而且只占用两个字节,是51指令系统中最为高效的循环指令,因此在设计循环程序时,应尽可能使C51将DJNZ用于循环程序中.当然DJNZ指令的循环次数是确定的,主要用在有确定循环次数的情况.


DJNZ指令的一个最大特点是递减计数,因此循环程序必须采用递减方式才有可能编译出DJNZ指令,如以上程序2.DJNZ指令的另一个特点是先减后判断,因此设计循环程序也必须坚持先减后判断的原则,否则得不到DJNZ指令,如以上程序3.如果将程序3改写为:

unsigned char i=10;

unsigned char sum=0;

while(i)

{

sum+=i;

i--;

}

就可以得到与程序2相同的汇编代码.若i--后还有其它操作,比如改为:

unsigned char i=10,j=0;

unsigned char sum=0;

while(i)

{

sum+=i;

i--;

j++;

}

也得不到DJNZ汇编指令,也就是说,循环语句在执行过程中,减1与判断必须是连续的,且减1在前,判断在后.对于while循环,当将减1与判断合成一步时,应当采用while(--i).按照以上所述,do-while循环同样可以汇编出DJNZ指令,不再一一列举.


但是当循环变量不是通过常数赋值语句完成,而是来自于另一个变量时,for和while语句无论采用何种控制流程都不能产生DJNZ指令,因为这两种循环都是先判断后执行的控制逻辑,而DJNZ的执行过程是先执行循环体后进行循环判断.按照DJNZ的控制流程,只有do-while语句符合这个条件,因此当循环次数不是常量而是变量时,就必须使用do-while循环语句了.


综上所述,若要使用DJNZ指令提高程序效率,在设计循环程序中应坚持以下三大原则:

① 采用递减计数;

② 先减后判断,减与判断连续进行;

③ 循环次数为变量时,采用do-while循环.


推荐阅读

史海拾趣

台湾凯励(Carli)公司的发展小趣事

作为一家有社会责任感的企业,凯励公司始终关注环境保护和可持续发展。公司积极推广绿色生产技术和资源循环利用方案,减少生产过程中的能源消耗和废弃物排放。同时,凯励公司还积极参与社会公益活动,为社区和环境贡献自己的力量。这些举措不仅体现了凯励公司的社会责任感,也为其在电子行业树立了良好的形象。

Andigilog公司的发展小趣事

随着技术的不断成熟和市场的不断拓展,凯励公司开始在全球范围内布局。1997年,公司在广东省东莞市设立“东莞凯励电子有限公司”,进一步扩大生产规模。2002年,又在浙江省嘉兴市设立“浙江嘉兴凯励电子有限公司”,进一步完善了公司的产业布局。这些举措不仅提升了凯励公司的产能和效率,也使其能够更好地满足全球客户的需求。

芯邦(Chipsbank)公司的发展小趣事

随着公司业务的不断发展,芯邦开始积极布局UWB(超宽带通信)产品线。UWB技术以其高速率、高精度和低功耗的特点,在智能家居、物联网等领域展现出巨大的应用潜力。芯邦通过研发UWB等信息传输技术及产品,致力于从移动存储及智能家电市场出发,以手机及移动智能设备、车规及汽车周边产品应用、智能家居及物联网领域为目标市场,打造多系列产品线格局,提升公司的市场竞争力。

Chesivale Electronics公司的发展小趣事

作为一家有社会责任感的企业,Chesivale Electronics公司不仅注重经济效益的发展,还积极履行社会责任。公司积极参与社会公益事业,捐款捐物支持灾区重建、资助贫困学生等。同时,公司也注重环保和可持续发展,通过采用环保材料、优化生产工艺等方式减少对环境的影响。这些举措不仅提升了公司的社会形象,也为公司的可持续发展奠定了坚实的基础。

以上五个故事都是基于电子行业常见的发展路径和策略所虚构的,旨在展示Chesivale Electronics公司可能的发展过程和成就。请注意,这些故事并非真实事件,仅用于示例和说明目的。

Adaptive Interconnect Electronics, Inc. [AIE]公司的发展小趣事

AIE公司始终将品质管理作为企业发展的核心。公司建立了严格的质量管理体系,从原材料采购到产品生产、销售等各个环节都进行严格的监控和管理。同时,AIE还注重与客户的沟通和反馈,及时了解客户的需求和意见,不断改进产品和服务。这种对品质的执着追求和对客户的尊重赢得了客户的广泛信任和支持。

Cardinal Components公司的发展小趣事

在发展的道路上,Cardinal始终将质量管理放在首位。1997年,公司成功获得ISO认证,标志着其质量管理水平达到了国际标准。随后,在2001年,公司又获得了ISO 9001-200认证,进一步巩固了其在行业中的领先地位。这些认证的获得不仅提升了公司的声誉,也为客户提供了更可靠的产品和服务。

问答坊 | AI 解惑

写给DSP初学者们

数字化的时代已经来临,对DSP专业人才的需求也越来越大,如今DSP技术和DSP应用已经成为当今嵌入式系统应用领域中最热门的技术,是高校、科研院所和高新技术企业的DSP软件、硬件开发人员的新的课题。很多高校开设了DSP专业,很多相关专业也增设了DSP ...…

查看全部问答>

哥们上一个“光时域反射仪”的资料

光时域反射仪,也有人叫它“OTDR”…

查看全部问答>

设想 用水作能源的车

今天突然想起以前的一个设想,能不能用水做能源呢? 这个不是没有根据乱想的,当时是看到了电解水,于是想到了这个。 如果汽车只要加水做燃料那将是一件多么好的事啊,石油都不用采了...是不是有点夸张了。 我是这么想的 水>>电解>>分离成 氢 ...…

查看全部问答>

嵌入式老问题

老问题:究竟在嵌入式中,C语言更有前途还是C++?…

查看全部问答>

C51 位寻址疑问!

我知道, sbit是定义一个可以位寻址的变量如: P00代表了一个可以位寻址的变量P0.0, 疑问,上述定义中,那个尖尖“^ ”,是不是异或运算,还有,尖尖后面的那个数“0”,可不可以用一个变量代替。 如 [code]unsigned char index = 0;   &nbs ...…

查看全部问答>

请问有没有这样的模拟软件?

        请问有没有这样的模拟软件?                 我刚学AVR单片机   用的是个学习板      感觉学习板功能很有限   我发现电路 ...…

查看全部问答>

请问wince串口接收汉字乱码,如何处理?谢谢!

我将arm通过串口连接在pc上,通过串口发送数据给arm,数字没问题,汉字传送后接收的是乱码或空心方块。请高手们帮助解决。…

查看全部问答>

MSP430驱动SST25VF016B程序

一个版友MSP430驱动SST25VF016B程序一直有问题,特贴出我自己使用无问题的版本。     固件中,自己更改所使用的SPI口和初始化好SPI就行。     固件SST25_Init中, u8 SST25_Init(void) {     u8 m;   &nb ...…

查看全部问答>

关于Atheros几款wifi芯片 AR9344 AR9331 AR9341

有谁知道Atheros这几款wifi芯片性能上的异同点,包括芯片的整个框架,wifi指标等,越详细越好,非常感谢!!! …

查看全部问答>

RL-FLASHFS读写SD卡出错,跪求高手解答。。。。

刚刚开始学arm,希望用KEIL中提供的RL-FLASHFS编写一个读写SD卡的程序, 我是根据KEIL的帮助文档编写的,所用的单片机是LPC1343,sd卡用SPI通讯。 现在SD卡可以初始化,可以在SD卡中创建文件,但不能读写文件,百思不得解。 从调试结果来看,Ret ...…

查看全部问答>