“我真的完全不明白。我看到网上莫名其妙的评论代码有它为什么这样做,许多周期的随机数,但硬是没有解释为什么什么做什么或在什么是谁,我真的不知道。“
“我明白,但我喜欢,不知道你从哪里得到EXACT时间,你如何计算它?这些数字从哪里来。如果我将VAR1设置为15,会发生什么变化。如果我将三个延迟变量设置为4,16,12,那么时间从何而来?这些数字会导致循环成为特定时间?谢谢 - Jimmy Page“
如果我理解您的问题则:
的16F690数据表表示:
一个指令周期由四个振荡周期为振荡器FREQUENC y为4 MHz,这给出了1μs的正常指令执行时间。除非条件测试为真或程序计数器因指令而改变,否则所有指令均在单个指令周期内执行。发生这种情况时,执行需要两个指令周期,第二个周期作为NOP执行。
因此,可以说延迟1的值是3,我们有这样的循环:
Top
decfsz Delay1,f
goto Top
我们每次执行DECFSZ我们时间获取股票一个周期。如果f为零,我们必须跳过,那么它变成了一个两周期的指令。每次我们执行goto时,pc都会改变,所以它是一个2周期的指令。所以,如果我们走循环,我告诉这个使用格式
延迟1值之前的指令,指令,使用周期来执行,总周期
3,decfsz,1,1
2,goto,2,3
2,decfsz,1,4
1,goto,2,6
1,decfsz,2,8
使环本身与延迟1开始的3拿了8周期或8us,如果我们在4mhz运行。首先计算周期,然后调整器件的时钟速率非常重要,相同的代码在2mhz运行时可能为16us,而在1mhz运行时可能为32us。
所以通过检查我们可以看出,对于f值不是1的情况,decfsz + goto对是2 + 1 = 3个周期。有一次,我们打到decfsz的值为1,这将是2个周期。因此,从3的Delay1开始,将有2个非一个入口值(3,2)。并且在上次我们击中decfsz并跳过时总共添加2个周期((3-1)* 3)+ 2 = 8。
如果我们已经进入这个Delay1设置为11的循环,它将是((11-1)* 3)+2 = 32个循环,一个7将是20个循环。
如果你继续往下走一个decfsz循环,你会继续乘以执行循环的次数。如果延迟1是一个3进入和延迟2是一个2
Top
decfsz Delay1,f
goto Top
decfsz Delay2,f
goto Top
然后第一次通过延迟1 DECFSZ,转到循环中,我们所知道的是8个周期。第一个decfsz Delay2,因为Delay2不是1是1的周期,我们总共达到了9。 goto是2个,共11个。假设f存储器是8位,那么当我们第二次点击Delay1循环时,我们输入0,把它看作是一个0x100或者256的数学运算给我们((256-1)3)+2 = 767 more到目前为止共有778个周期。 Delay2现在是1,所以这是最终的Decfsz Delay2,f这样花费我们2,总共780个周期。 (((Delay-1)(((256-1)* 3)+2))+(((Delay1)-1)* 3)的周期计算算法, +2)+((Delay2-1)* 3)+2个周期。
虽然我的循环是由一个DECFSZ环比你小的,如果你让我的像你,因为它与其他一些指令开始:
Entry
movlw .3
movwf Delay1
movl2 .2
movwf Delay2
Top
decfsz Delay1,f
goto Top
decfsz Delay2,f
goto Top
我们需要增加4个周期以上两个MOVLW的以及两个movwf到要执行的周期数的总体方程。
因此,从字面上看,有一个解释它为什么执行如此多的循环。这个解释在设备的数据表中。
让我们继续深入。让我们得到的代码生成器,patrickmdnet链接到生成780个周期:
; Delay = 780 instruction cycles
; Clock frequency = 4 MHz
; Actual delay = 0.00078 seconds = 780 cycles
; Error = 0 %
cblock
d1
d2
endc
;778 cycles
movlw 0x9B
movwf d1
movlw 0x01
movwf d2
Delay_0
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_0
;2 cycles
goto $+1
这个循环的架构有点不同。
我们先从装载在F寄存器的4个周期之前,我们得到Delay_0
内DECFSZ循环转到不直接在你的问题的代码和我上面的解释分支与Delay_0,这一跳过decfsz d2,f。因此,对于没有人通过该循环,decfsz有1个循环,goto $ + 2有2个循环,delay_0有2个循环,每个非d1有5个循环。并且在d1是1的时候再加两个。这给了我们((0x9B-1)* 5)+2 = 772个周期加上了4个周期,然后我们达到了776个周期。
有趣的是,最后一个decfsz d1,f命中一个decfsz d2,f,并将d2设置为0x01,这意味着它保证跳过。它是2个周期,转到$ + 2与另一个转到$ + 1而不是movlw/movwf加载d2会做同样的事情。反正2个周期的这个单指令给我们带来最多,共778个周期
我们需要两个以上的周期才能到780和与一个goto $ + 1在这里完成,goto方法修改PC所以他们总是2周期。我要求程序生成780个周期。
这个汇编代码究竟是哪个CPU? – zwol 2011-02-12 01:54:19
16F690我想回答你的问题 – 2011-02-12 02:38:55
你的例子是不完整的(它从来没有使用`Delay3`),我不知道你为什么认为它循环回到&&&&`。你是怎么想出来的? – Gabe 2011-02-12 03:04:47