音影先锋亚洲天堂网|电影世界尽头的爱完整版播放|国产 熟女 91|高清无码免费观看欧美日韩|韩国一区二区三区黄色录像|美女亚洲加勒比在线|亚洲综合网 开心五月|7x成人在线入口|成人网站免费日韩毛片区|国产黄片?一级?二级?三级

登錄 免費(fèi)注冊(cè) 首頁 | 行業(yè)黑名單 | 幫助
維庫電子市場網(wǎng)
技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測(cè)控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng)
驅(qū)動(dòng)編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機(jī) | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計(jì) | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe

Keil C51的一些有趣特性

作者:yanfengzhu 欄目:單片機(jī)
Keil C51的一些有趣特性
首先得說的是我是菜鳥,在此論壇上學(xué)了很多的東東。但是今年以來,論壇上似乎沒有了去年一大幫高手討論問題的場面了,似乎失去了往日的風(fēng)光了。在此我那出我近日一些不成熟的想法,希望大家斧正。有啥不正確的,請(qǐng)一定告之與我。

Keil C51的一些有趣特性



作者:yanfeng

E-mail:szq106@163.com



Keil c51號(hào)稱作為51系列單片機(jī)最好的開發(fā)環(huán)境,大家一定都很熟悉。它的一些普通的特性大家也都了解,(書上也都說有)如:因?yàn)?1內(nèi)的RAM很小,C51的函數(shù)并不通過堆棧傳遞參數(shù)(重入函數(shù)除外),局部變量也不存儲(chǔ)在堆棧中,而是存在于固定的RAM中及寄存器中。那么看一下下面的程序。

void fun1(unsigned CHAR i)

{

       …

}

正常情況參數(shù)i通過R7傳入函數(shù),那么它的實(shí)際地址在什么地方呢?就是R7嗎?回答這個(gè)問題之前我們先來了解keil c51的幾個(gè)有趣的特性(不考慮重入函數(shù))。



一、              函數(shù)在調(diào)用前定義與在調(diào)用后定義產(chǎn)生的代碼是有很大差別的(特別是在優(yōu)化級(jí)別大于3級(jí)時(shí))。(本人也不太清楚為什么,大概因?yàn)樵谡{(diào)用前定義則調(diào)用函數(shù)已經(jīng)知道被調(diào)用函數(shù)對(duì)寄存器的使用情況,則可對(duì)函數(shù)本身進(jìn)行優(yōu)化;而在調(diào)用后進(jìn)行定義則函數(shù)不知被調(diào)用函數(shù)對(duì)寄存器的使用情況,它默認(rèn)被調(diào)用函數(shù)對(duì)寄存器(ACC、 B、 DPH、 DPL、 PSW、 R0、 R1、 R2、 R3、R 4、 R5、, R6、 R7)都已經(jīng)改變,因此不在這些寄存器中存入有效的數(shù)據(jù))

二、              函數(shù)調(diào)用函數(shù)時(shí)除在堆棧中存入返回地址之外,不在堆棧中保存其它任何寄存器(ACC、 B、 DPH、 DPL、 PSW、 R0、 R1、 R2、 R3、R 4、 R5、, R6、 R7)的內(nèi)容。(除非被調(diào)用函數(shù)使用了using特性)

三、              中斷函數(shù)是一個(gè)例外,它會(huì)計(jì)算自身及它所調(diào)用的函數(shù)對(duì)寄存器(ACC、 B、 DPH、 DPL、 PSW、 R0、 R1、 R2、 R3、R 4、 R5、, R6、 R7)的改變,并保存相應(yīng)它認(rèn)為被改變了的寄存器。

四、              使用C寫程序時(shí),盡量少使用using n (n=0,1,2,3)特性。(這個(gè)特性在本人使用的過程中存在一些問題,不知算不算是一個(gè)小bug)

以下的試驗(yàn)都是在(環(huán)境 keil c51 v7.20)中,優(yōu)化級(jí)為default下完成。



先看第一個(gè)特性問題。

例1:

void fun2(void)

{

}



void fun1(unsigned CHAR i)

{

       fun2();

       while(i--);

}

它的匯編代碼如下:

; void fun2(void)



       RSEG  ?PR?fun2?TEST

fun2:

                     ; SOURCE LINE # 12

; {

                     ; SOURCE LINE # 13

; }

                     ; SOURCE LINE # 14

       RET      

; END OF fun2



;

; void fun1(unsigned CHAR i)



       RSEG  ?PR?_fun1?TEST

_fun1:

       USING    0

                     ; SOURCE LINE # 16

;---- Variable 'i?240' assigned to Register 'R7' ----

; {

                     ; SOURCE LINE # 17

;     fun2();

                     ; SOURCE LINE # 18

       LCALL       fun2

?C0003:

;     while(i--);

                     ; SOURCE LINE # 19

       MOV         R6,AR7

       DEC         R7

       MOV         A,R6

       JNZ         ?C0003

; }

                     ; SOURCE LINE # 20

?C0005:

       RET      

; END OF _fun1

從中可以看到fun2()在fun1()前先定義,fun1()知道fun2()對(duì)寄存器的使用情況,知道R7沒有改變,而參數(shù)i存于R7中,即i既是R7。(;---- Variable 'i?140' assigned to Register 'R7' ----)



看另一情況

void fun2(void);

void fun1(unsigned CHAR i)

{

       fun2();

       while(i--);

}



void fun2(void)

{

}

匯編代碼如下:

; void fun1(unsigned CHAR i)



       RSEG  ?PR?_fun1?TEST

_fun1:

       USING    0

                     ; SOURCE LINE # 14

       MOV         i?140,R7

; {

                     ; SOURCE LINE # 15

;     fun2();

                     ; SOURCE LINE # 16

       LCALL       fun2

?C0002:

;     while(i--);

                     ; SOURCE LINE # 17

       MOV         R7,i?140

       DEC         i?140

       MOV         A,R7

       JNZ         ?C0002

; }

                     ; SOURCE LINE # 18

?C0004:

       RET      

; END OF _fun1



;

; void fun2(void)



       RSEG  ?PR?fun2?TEST

fun2:

                     ; SOURCE LINE # 20

; {

                     ; SOURCE LINE # 21

; }

            &nbs
2樓: >>參與討論
enbed
這個(gè):
由此可以推論出,一個(gè)高優(yōu)先級(jí)的中斷函數(shù)及一個(gè)低優(yōu)先級(jí)的中斷函數(shù)同時(shí)使用了using n,(n = 0,1,2,3)當(dāng)n相同時(shí),這個(gè)存在的bug 是多么的隱蔽。(這恰是使人想象不到的)


你沒有用過匯編把.


一般匯編都這么用,會(huì)自己事先把四個(gè)寄存器組分配好的.

3樓: >>參與討論
meng730507
有點(diǎn)意思!
 
4樓: >>參與討論
來與君
在不同的中斷服務(wù)例程中使用寄存器組切換時(shí)
在using上是要仔細(xì)處理的

沒有什么理由在用匯編寫時(shí)就很細(xì)心,而用C寫時(shí)就可以馬虎這種道理的。

畢竟開發(fā)環(huán)境這個(gè)工具不是完美的。

5樓: >>參與討論
yanfengzhu
謝謝兩位捧場。
 
6樓: >>參與討論
yanfengzhu
to enbed
我是從匯編學(xué)起的,要說不懂也懂那么一點(diǎn)。(也許不比論壇上的大部分人差哦。
用匯編來寫我肯定不會(huì)出這個(gè)錯(cuò)誤!但是C語言是編譯器編譯的。這個(gè)就不大好說了。比如定時(shí)器0和定時(shí)器1中斷函數(shù)同時(shí)使用了using 1,而定時(shí)器0設(shè)為低優(yōu)先級(jí),定時(shí)器1設(shè)為高優(yōu)先級(jí)。在某種情況下,定時(shí)器0進(jìn)入中斷后,定時(shí)器1也進(jìn)入中斷。這樣形成兩級(jí)中斷嵌套。由于中斷函數(shù)使用了using 1不再保存R0 -- R7的值,當(dāng)定時(shí)器0中斷函數(shù)在R0--R7中存放有重要數(shù)據(jù)而定時(shí)器1中斷函數(shù)破壞了R0--R7的值時(shí),程序會(huì)出現(xiàn)什么情況就很難說了。因?yàn)橹袛嗲短壮霈F(xiàn)的情況本身不是常見,而高低級(jí)中斷函數(shù)都使用R0--R7情況也不多,因此才說這個(gè)bug很隱蔽。

7樓: >>參與討論
yanfengzhu
to 來與君
謝謝!
不是說寫程序馬虎,只是發(fā)現(xiàn)了提出來提示大家,免得犯同樣的錯(cuò)誤。

8樓: >>參與討論
enbed
來與君的是正解.
這個(gè)問題是你不同的中斷錯(cuò)誤的使用同一個(gè)寄存器組,怎么能說是編譯器的錯(cuò)誤?



9樓: >>參與討論
狂日
GLOBAL Register Coloring
對(duì)于“函數(shù)在調(diào)用前定義與在調(diào)用后定義產(chǎn)生的代碼是有很大差別的”
請(qǐng)打開GLOBAL Register Coloring開關(guān)試試!

10樓: >>參與討論
zalin
沒仔細(xì)看使用手冊(cè)

KEIL C51的使用手冊(cè)對(duì)中斷函數(shù)使用“USING”和在中斷函數(shù)中調(diào)用函數(shù)有明確的說明

不同優(yōu)先級(jí)的中斷函數(shù)不要使用相同的寄存器BANK,假如使用了“USING”

在中斷函數(shù)中被調(diào)用的函數(shù)應(yīng)和中斷函數(shù)使用相同的寄存器BANK,除非對(duì)被調(diào)用的函數(shù)使用“NOAREGS”

11樓: >>參與討論
cxd731
C51的書沒啃透!
 
12樓: >>參與討論
yanfengzhu
謝大家
to enbed
   51本身沒有限定不同的中斷不能使用同一個(gè)寄存器組。Keil c51不能這么使用本身不能不是說存在小瑕疵,而且我并沒說這是編譯器的大錯(cuò)誤。甚至于算不算一個(gè)小bug也還有待商榷。

to 狂日
    GLOBAL Register Coloring是優(yōu)化級(jí)別還是?
to zalin
    老實(shí)說,KEIL C51的使用手冊(cè)的確實(shí)沒仔細(xì)看,謝謝提醒。

謝謝各位。

13樓: >>參與討論
foolembed
你是翻譯的,還是自己寫的啊,呵呵:)
keil的手冊(cè)可是差不多都有了把,
會(huì)總結(jié)的人,進(jìn)步最快,欣賞:)

由此可以推論出,一個(gè)高優(yōu)先級(jí)的中斷函數(shù)及一個(gè)低優(yōu)先級(jí)的中斷函數(shù)同時(shí)使用了using n,(n = 0,1,2,3)當(dāng)n相同時(shí),這個(gè)存在的bug 是多么的隱蔽。(這恰是使人想象不到的)

正如enbed所說,用過asm的人,應(yīng)該知道寄存器保護(hù)的,而且keil也很明確的告訴了大家:千萬不要這樣使用using在中斷編程的時(shí)候:),
keil的資料大把,高手n多,
但感謝你將這樣的資料翻譯或者是整理出來,很多初學(xué)者還是會(huì)很受用的:)
贊!

14樓: >>參與討論
yanfengzhu
to foolembed
是我自己寫的,因?yàn)榻鼇碓谡夜ぷ鳎]人要。苁聼o聊,于是想學(xué)習(xí)一下OS,在寫os的過程中發(fā)現(xiàn)這些有趣的東東的。我的小OS就寫好了,最大的特點(diǎn)的全C寫成,沒有一句匯編。有時(shí)間整理上來,到時(shí)望各位高手指教.

15樓: >>參與討論
nizq
GOOD。!
 
16樓: >>參與討論
hunter01
并不是什么bug,中斷優(yōu)先級(jí)不同,不一定就嵌套.
中斷優(yōu)先級(jí)不同,不一定就嵌套,進(jìn)入地優(yōu)先級(jí)中斷,可可以屏蔽一下高優(yōu)先級(jí)中斷, 編譯器編譯的結(jié)果是正確的。
而且兩個(gè)中斷不可能同時(shí)出現(xiàn)的 情況也是經(jīng)常用到的的,比如在產(chǎn)口中斷里啟動(dòng)和停止定時(shí)器


* - 本貼最后修改時(shí)間:2005-6-2 20:15:41 修改者:hunter01

17樓: >>參與討論
來與君
再進(jìn)來是為了稱贊樓主的
嘗試著去剖析一個(gè)工具是為了更好地利用它,我偶爾也這么做。

你提到的“51本身沒有限定不同的中斷不能使用同一個(gè)寄存器組。Keil c51不能這么使用本身不能不是說存在小瑕疵,而且我并沒說這是編譯器的大錯(cuò)誤。甚至于算不算一個(gè)小bug也還有待商榷!

就另外一件事情來看,我是這么理解Keil的。

以帶Carry位的移位操作來說,在某些應(yīng)用中,用ASM來實(shí)現(xiàn)非常有用且高效,但在Keil C中未有直接對(duì)應(yīng)的操作指令。這是Keil對(duì)CY位不了解嗎?不會(huì)用嗎?在這上面它考慮的也許更多的是一個(gè)C程序的移植。

因此,不要因?yàn)槟承┓矫鍯沒有如ASM一般動(dòng)作而直接否定Keil C的機(jī)理。我想,Keil在51場子里頭摸爬滾打這么些年,它對(duì)51的特性比我們稍熟一些。

當(dāng)然,Keil C也有Bug,這從它的發(fā)行筆記中就可以看到。不過,這些Bug往往不在51的特性上。

18樓: >>參與討論
st963432

 
19樓: >>參與討論
gxlww
高!
 
20樓: >>參與討論
go_by_wind
好帖子呀,頂一下。。
 
21樓: >>參與討論
rogerllg
不錯(cuò)
還是頂一下。。。。。          

22樓: >>參與討論
zj_hfp
很好
我在實(shí)際調(diào)試中,遇到一個(gè)怪事,要在代碼中加入 ACC=0XFF;,原因可能是hfpfx的數(shù)變了,是取ACC的數(shù)了。真怪。
for(i=0;i<6;i++)    //提升位置處理
{    
  ACC=0XFF;         //系統(tǒng)內(nèi)部原因一定要加
  tmp=hfpfx<<i;
  tmp=tmp&0x80;
  tmp1=hfpfx1<<i;
  tmp1=tmp1&0x80;
  ACC=0;
  if (tmp!=tmp1)
  send[i]=0;
  }
        

23樓: >>參與討論
icxlh
向強(qiáng)者學(xué)習(xí)
 
24樓: >>參與討論
haotz
瞎掰
 
25樓: >>參與討論
yanfengzhu
to haotz
此帖正是瞎掰,偶爾有閑情瞎掰一下也是好事嘛。

26樓: >>參與討論
莊莊
請(qǐng)問怎樣能把反匯編的程序復(fù)制出來,謝謝
你這里既有C語言源程序又有匯編程序,請(qǐng)問怎樣能把反匯編的程序復(fù)制出來,謝謝

27樓: >>參與討論
xuefeihu
ding yixia
 
28樓: >>參與討論
ypli
挺不錯(cuò)的!善于發(fā)現(xiàn)和思考!我喜歡!
 
29樓: >>參與討論
leejun101
高手啊,俺是初學(xué)者
 
30樓: >>參與討論
235
太帥了。
真的,以前寫程序,只要能執(zhí)行的通就行,從不會(huì)關(guān)心代碼優(yōu)化的問題。這次算開眼界了。

呵呵,頂。

參與討論
昵稱:
討論內(nèi)容:
 
 
相關(guān)帖子
關(guān)于at89c54中ram使用的問題
請(qǐng)教,如何用軟件產(chǎn)生3次,7次諧波的波形的算法?
急急急,關(guān)于脈沖高電平低電平比較寬度問題望能知道得更詳細(xì)些
請(qǐng)教,如何才能得到頭文件中的原型函數(shù)?
怎樣檢測(cè)低電平寬度,我急啊,嗯嗯
免費(fèi)注冊(cè)為維庫電子開發(fā)網(wǎng)會(huì)員,參與電子工程師社區(qū)討論,點(diǎn)此進(jìn)入


Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號(hào)