1
2
f3第三种将do循环改成while循环,汇编代码也很复杂,有15行。
voiddelayu
sig
edcharx
u
sig
edcharijwhilex
i2j240whilei
whilej
voidmai
delay1
4第四种是for循环,汇编代码最复杂,有23行之多。
voiddelayu
sig
edcharx
u
sig
edcharijforx0xi2j240fori0i
forj0j
voidmai
delay1
3
f三、详细分析比较以上四种循环,第一种的汇编代码最为简单,结构最为清晰,极力推荐这种结构。
下面就对这种循环进行详细的分析先看C语言,x循环是为了调用时能够指定延时的整倍数而添加上去的,分析时可以暂
不管它,只要分析i循环以及嵌套的内层j循环就可以了。特别要注意的是i、j的赋值语句在循环以外,这一点很重要,也很巧妙。为了方便分析将汇编代码抄写在下面并写出执行一次所占用的机器周期(89C51):
C0x000FMOVR60x02
1T
C0x0011MOVR5B0xF0
1T
C0x0013DJNZR5C0013
2T
C0x0015DJNZR6C0013
2T
C0x0017DJNZR7delayC000F2T
C0x0019RET
2T
C0x001AMOVR70x01
1T
C0x001CLJMPR7delayC000F2T
①第1行是将2的十六进制数0x02放入寄存器R6,相当于C语言里给i赋值。第2行是将240的十六进制数0xF0放入寄存器R5,相当于C语言里给j赋值。这两行共占用了2T(T是机器周期)。
②第三行是将寄存器R5里的值减1,如果结果不为0即回到第三行再次执行,直到R5里的值等于0,才向下执行第四行。这一行在这一循环里共执行j240次,占用机器周期为2T×j。
③第三行执行了j次,第j次执行前寄存器R5里的值为1,第j次执行时减去1等于0,因此不再回到本行而是向下执行第四行,先前寄存器R6里的值是i2,第四行执行时先减1,结果为1,不等于0,就重新跳转到第三行。第四行这一次只执行了1次,因此占用机器周期是2T。
④戏剧性的时刻到了。由于在循环以外赋的值,重新跳转到第三行时寄存器R5里的值已经是0,减去1后溢出变成FF(十进制256),因此第三行这一次循环要执行256次,占用机器周期为2T×256。
⑤第三行执行了256次后重新回到第四行,此时寄存器R5里的值是1,第四行执行时减去1后等于0,因此不再跳转到第三行而是转向执行下面的行。第四行这一次又执行了1次,占用机器周期为2T。
如果当初放入寄存器R6的值不是2,而是i,显然④⑤要重复i1次,因此,④⑤占用的机器周期为2T×2562T×i12T。
⑥第6行是退出子函数返回主函数,占用机器周期为2T。⑦第七行是主函数调用延时子函数时的实参赋值,占用机器周期为1T。第八行是r