最好從編譯出來的匯編代碼來比較
- 20 void delayus(unsigned char i)
- 21 {
- 22 1 while(i--);
- 23 1 }
- 24 void delayu(unsigned char i)
- 25 {
- 26 1 unsigned char a;
- 27 1 for(a=0; a<i; a++)
- 28 1 {
- 29 2 _nop_();
- 30 2 }
- 31 1 }
- 下面來說說匯編的傳統計算方法:
-
- 指令周期、機器周期與時鐘周期
- 指令周期:CPU執行一條指令所需要的時間稱為指令周期,它是以機器周期為單位的,指令不同,所需的機器周期也不同。
- 時鐘周期:也稱為振蕩周期,一個時鐘周期 =晶振的倒數。
- MCS-51單片機的一個機器周期=6個狀態周期=12個時鐘周期。
- MCS-單片機的指令有單字節、雙字節和三字節的,它們的指令周期不盡相同,一個單周期指令包含一個機器周期,即12個時鐘周期,所以一條單周期指令被執行所占時間為12*(1/12000000)=1us。
- 了解了上面這些我們來看一個例子
-
- 匯編延時子程序的延時計算問題
- 對于程序
- ; FUNCTION _delayus (BEGIN)
- ; SOURCE LINE # 20
- ;---- Variable 'i' assigned to Register 'R7' ----
- ; SOURCE LINE # 21
- ?C0008:
- ; SOURCE LINE # 22
- MOV R6,AR7 ;2指令周期
- DEC R7 ;1指令周期
- MOV A,R6 ;1指令周期
- JNZ ?C0008 ;2指令周期
- ?C0009:
- ; SOURCE LINE # 23
- ?C0010:
- RET ;2指令周期
- ; FUNCTION _delayus (END)
- R7 * (2+1+1+2) + 2
- 整個循環執行完應該是 =(R7 * 6) + 2 指令周期
- ; FUNCTION _delayu (BEGIN)
- ; SOURCE LINE # 24
- ;---- Variable 'i' assigned to Register 'R7' ----
- ; SOURCE LINE # 25
- ; SOURCE LINE # 27
- ;---- Variable 'a' assigned to Register 'R6' ----
- CLR A ;1指令周期
- MOV R6,A ;1指令周期
- ?C0011:
- MOV A,R6 ;1指令周期
- CLR C ;1指令周期
- SUBB A,R7 ;1指令周期
- JNC ?C0014 ;2指令周期
- ; SOURCE LINE # 28
- ; SOURCE LINE # 29
- NOP ;1指令周期
- ; SOURCE LINE # 30
- INC R6 ;1指令周期
- SJMP ?C0011 ;2指令周期
- ; SOURCE LINE # 31
- ?C0014:
- RET ;2指令周期
- ; FUNCTION _delayu (END)
- (1+1+1+2)+ R7 * (1+1+2+1+1+1+2) +1 +1 +2
- 整個循環執行完應該是 = (R7 * 9) + 9 指令周期
- 還說明一下:
- nop指令或者_nop_(); 函數占一個機器周期,
- 在stc單片機的12T模式下一個機器周期是一個振蕩周期的12分頻,如果你的晶振是12MHZ,那你的一個機器周期就是1微秒.一個nop指令的執行時間也就是1US
- 當在6T模式(下載的時候可選擇模式)下12M晶振的時候,一個nop就是0.5US了.
復制代碼 |