<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 慎用51單片機中的RET指令

慎用51單片機中的RET指令

作者: 時(shí)間:2016-11-20 來(lái)源:網(wǎng)絡(luò ) 收藏
題目:已知有四個(gè)按鍵依次連接單片機中的P3口的0到3的IO口,有四個(gè)LED燈連接P1的0到3 IO口,寫(xiě)一程序,滿(mǎn)足以下條件:當按下按一個(gè)按鍵,對應的LED會(huì )發(fā)亮,比如

按下P3.0的按鍵,連接P1.0的LED就發(fā)亮。y

本文引用地址:http://dyxdggzs.com/article/201611/318611.htm

以下是我同學(xué)編寫(xiě)的程序:

org 0000h
mov P1,#0ffh
loop:
jnb P3.0,led1;*
jnb P3.1,led2;*
jnb P3.2,led3;*
jnb P3.3,led4;*
ljmp loop
led1:
clr P1.0
ret
led2:
clr P1.1
ret
led3:
clr P1.2
ret
led4:
clr P1.3
ret
end

程序的意圖是,制造一個(gè)死循環(huán),不斷檢查按鍵是否按下,如果按下,就令對應的燈亮。程序經(jīng)過(guò)測試,能夠滿(mǎn)足題目的要求。

但是,問(wèn)題出現在上面帶*號的那一部分代碼,程序意圖是想要當P3的某個(gè)位為0的時(shí)候,就調用LED燈的子程序,執行CLR P1.0語(yǔ)句,再返回到原來(lái)程序調用子程序的地方繼續執行代碼。

我對的子程序的理解是:在一個(gè)地方啟動(dòng)一段代碼,當這段代碼運行完畢之后,就返回到原來(lái)的地方繼續運行剩下的代碼。

那么CPU單片機是如何返回原來(lái)的地址的呢?

首先,當程序執行到A處進(jìn)入子程序時(shí),將A的下一個(gè)條指令(即PC+2所指的地方)壓入棧中,即將棧指針SP+1,PCL進(jìn)棧,SP再加1,PCH進(jìn)棧。

然后,把PC的值改為子程序代碼的入口。

子程序執行完畢之后,從棧中彈出原來(lái)的PC值,賦值給當前的PC寄存器。


最后,程序返回到原來(lái)調用子程序的地方的下一條指令繼續運行。

(詳細步驟請查看RET和ACALL,LCALL指令)

上面的代碼很明顯想調用一個(gè)子程序,但是51單片機中,只有ACALL和LCALL指令會(huì )在跳轉前講PC+2值壓棧,其他跳轉指令都不會(huì )。

代碼中使用了JNB作為跳轉指令,所以并沒(méi)有壓棧,但是當跳轉之后遇到RET,還是一如既往地彈棧,這樣,只有出,沒(méi)有進(jìn),會(huì )導致堆棧不平衡。

但為什么這個(gè)程序依然有效呢?

這個(gè)因為SP初始指針指向了一個(gè)空白的單元(全是0),所以,當遇到RET后,把PC寄存器給初始化,程序由頭開(kāi)始重新執行,陰差陽(yáng)錯地滿(mǎn)足的題目的要求。

所以RET指令必須和ACALL和LCALL配套使用,才能組成為真正意義上的子程序



關(guān)鍵詞: 51單片機RET指

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>