微控制器的子程式 子程式和中斷服務子程式 中是不是最後不能用LJMP之類的跳轉指令的?只能是RET或

2021-05-12 07:00:38 字數 5699 閱讀 1686

1樓:匿名使用者

簡單來說,可以這樣理解沒錯。

ret/reti指令本身已經包含了從stack中pop pc的操作。

2樓:做而論道

call 和 ret ,這兩條指令,要配套使用。

jmp 和 reti,不屬於它們,不可濫用。

微控制器中,能否使用ljmp指令從主程式轉入子程式或從子程式跳轉回主程式,為什麼

3樓:匿名使用者

這個當復

然是能使用ljmp指令重主程式跳轉制到子程式,或從子程式跳回主程式,但一般是不允許這樣使用ljmp指令的,很容易造成程式執行混亂。因為呼叫子程式保護現場要將當前的地址壓入堆疊,子程式返回時,會彈出該地址賦值給pc指標。如果使用,必須滿足以下條件:

1、跳出跳入成對出現,也就是說,從主程式用ljmp跳轉到子程式,那麼在子程式中的ret前,必須是用ljmp指令跳回。

2、不成對出現,但是如果子程式是ljmp跳轉來的控制,那麼在ret前,需要壓入返回位置的地址。比如:

主程式:

.....

ljmp  sub01

........

con: ;返回地址

......

sub: ;子程式

....

sub01: ;跳轉到的地址

....

mov dptr,#con ;返回前處理。

push dph

push dplret

4樓:匿名使用者

不能這樣bai寫程式。

如果這樣寫了du,程式也zhi會按照指令順序執行dao,但是很容易出現內

問題,導致程式跑容飛。

由於微控制器的ram是有限的,程式在進入子程式之前經常會使用ram來臨時儲存一些資料,包括sp指標在執行完子程式之後需要跳回的地址資訊。也就是堆疊的「壓棧」(push)。

子程式執行完後,要執行一個ret指令結束子程式,指標指向的堆疊單元讀取堆疊資料,這個過程叫做「出棧」(pop ),然後指標會正常的執行下去。

假如在子程式內直接用ljmp指令跳出到主程式,就會把堆疊壓入的資料沒有讀出,造成資料丟失,sp指標指向的地址沒有正確返回,造成堆疊不斷增加,直到不夠用了就會溢位。

再假如從主程式內直接用ljmp指令跳入子程式,在執行ret退出子程式時,就會造成錯誤的讀出堆疊內的資料。

5樓:匿名使用者

絕對不可以

會造成邏輯的混亂,因為堆疊會亂。

call的子程式的最後的返回需用 ret 語句而長轉移只能用在本段程式內(如主程式內或子程式內)而步能在2個之間跳轉。

6樓:快樂珍惜

如果是bailjmp 跳轉du的返回時需要 跳轉返回,不能使用zhi ret返回;

如果是call 呼叫dao子函回數,的返回可以使答用 ret 返回;

主要原因是call 的時候有自動 堆疊 動作,ret 會自動出棧,使棧保持平衡;否則會導致堆疊破壞和堆疊溢位;

滿意的話贊一個!

微控制器能否使用ljmp指令從主程式轉入子程式或從子程式跳回主程式,為什麼? 10

7樓:匿名使用者

這個當然是bai能使用ljmp指令du重主程式跳轉到子程式,或從zhi子程式跳回主dao程式,但一般是

回不允許這樣使用答ljmp指令的,很容易造成程式執行混亂。因為呼叫子程式保護現場要將當前的地址壓入堆疊,子程式返回時,會彈出該地址賦值給pc指標。如果使用,必須滿足以下條件:

1、跳出跳入成對出現,也就是說,從主程式用ljmp跳轉到子程式,那麼在子程式中的ret前,必須是用ljmp指令跳回。

2、不成對出現,但是如果子程式是ljmp跳轉來的控制,那麼在ret前,需要壓入返回位置的地址。比如:

主程式:

.....

ljmp  sub01

........

con: ;返回地址

......

sub: ;子程式

....

sub01: ;跳轉到的地址

....

mov dptr,#con ;返回前處理。

push dph

push dplret

8樓:匿名使用者

這是一條無條件轉移指令,而且是長轉移,轉移可達64k,已完全覆蓋51微控制器的程式空間,只要利用對應的標號,完全可以從主程式轉入子程式或從子程式跳回主程式。

9樓:

可以的,但要在相應跳轉處設好標籤

請問51微控制器的中斷服務子程式中能否加跳轉指令

10樓:填盍

中斷服務子程式,你指的的是哪部分的?如果是產生中斷後,硬體自動跳轉到中斷服務入口處,執行的那個程式的話,必須加跳轉。因為每個中斷入口後僅分配給該中斷服務程式8位元組的指令空間,只能用於保護現場並跳轉到真正的中斷服務程式,執行完後用ret指令跳回這裡,再用reti指令跳回主程式。

當然,在真正的中斷服務程式中也可以加跳轉指令,而且跳轉指令作用很多,可以用於多路分支程式和查表程式

11樓:匿名使用者

看你跳到**

在中斷子程式內部跳跳隨便你

要是跳轉範圍跑到中斷程式外面,你的程式早晚因為堆疊滿了跑飛

12樓:匿名使用者

當然可以了,在中斷向量地址處就可以加一條跳轉指令,中斷程式中也可以使用的。

51微控制器子程式中使用jmp(ajmp,ljmp,sjmp)指令 執行ret能不能回到主程式?

13樓:風間一葉

我仔細看了一下所有人的回答,有根本沒看懂樓主問題答非所問的,也有回答的差不離的,我來切一下重點好了。

樓主這所有問題其實歸根結底就是一個問題,堆疊和sp(堆疊指標)的問題

call指令執行時,就是先把當前程式指標壓入堆疊並使sp加1,然後開始執行call指令呼叫的子程式,當遇到ret指令時,把前面壓入堆疊的程式指標取出並sp減1(出棧),然後就回到call程式呼叫前位置了。

jmp指令並不會把程式指標壓入堆疊更不會影響sp(當然自己在jmp後用push指令除外)。自然call呼叫後使用jmp指令跳轉,最後遇到ret指令一樣能回到call程式呼叫前位置。就算你在jmp指令後使用push指令,只要和pop成對出現,還是會回到呼叫前的位置,不成對?

這堆疊不能這麼用的。。飛了。。飛了。

中斷其實和call指令時一樣的道理,至於用reti就如張庚(3樓)兄弟說的中斷是要多處理一些標誌位。

至於呼叫call多少次出錯,這還是堆疊和sp的問題。

如我上面所寫,call指令一次就得壓棧一次,而你在ret指令前又來一次call指令,那麼還得壓一次,這樣一直下去堆疊指標愈來愈大,就會佔用程式所要使用的ram地址,自然肯定會出錯,一半51微控制器預設sp為07h,而一般程式設計ram地址20h開始就會被程式佔用,一算就知道了,大概10幾20次吧,如果你中間還是用堆疊那麼就少點,如果你的程式佔用ram的地址靠後那麼就多點,不過一般夠用是肯定的了

14樓:做而論道

jmp(ajmp,ljmp,sjmp)指令,是轉移指令,它們在轉移的時候,並不保留當前的地址,所以使用ret指令,是無法回到原來的位置的。

使用lcall、acall指令,就是呼叫子程式的指令,是可以用ret指令返回的,因為lcall、acall指令儲存了原來的地址,可供ret使用。

另外,中斷程式中是可以使用jmp指令的,但是要保證,要儘快使用reti返回原來的斷點,否則就一直處於中斷之中,cpu以後就不會再相應同級別的中斷了。

------------------------

問題補充:

...,最後使用ret能不能回到call(acall,lcall)呼叫前的位置?

可以。...,多少次就會出錯?

lcall、acall指令儲存了原來的地址,是存放到堆疊裡面。

51微控制器的堆疊,是在片內ram中,空間是有限的。

空間究竟有多大,和你的棧底初始化的地址有關,另外,堆疊中,還會儲存其它的內容。所以,儲存返回地址的空間究竟能有多大,需要你自己計算。

多少次會出錯,是和你編寫的程式有關的。

你可以用keil軟體來除錯,把你的程式單步的執行走一遍,即可知道堆疊空間的使用情況了。

15樓:lixiao瀟瀟瀟

在子程式內用跳轉可以。但是如果在子程式內用跳轉 跳出了這個子程式執行別的去了,這個就要小心了,你的ret沒有執行(地址沒有出棧),可能會出現資料的錯誤,如果後面反覆呼叫該函式 也有可能因為地址只進棧不出棧 導致最終記憶體佔滿。

16樓:宇潔

我個人覺得你好像把這些指令的功能弄混了,jmp(ajmp,ljmp,sjmp)指令這些指令時單純的跳轉指令,比如jmp loop 這條指令,就是程式跳轉到loop這個地方去執行,並沒有什麼返回不返回的說法,除非執行過程中遇到別的指令。這幾個指令的區別的跳轉的距離,有短跳轉,長跳轉,這些你去看看指令表應該就知道了。

至於ret 是專門給子程式呼叫的時候用的,當你呼叫一個子程式,子程式執行完之後,必須要寫一個ret 這個指令,用來返回你呼叫子程式的那句程式的位置,以便程式繼續執行。

而reti 是專門給中斷子程式使用的,是用來做中斷返回用的。

這兩個指令跟jmp沒有關係,使用的時候在子程式裡依然可以使用jmp,但需要注意的是你用完jmp就不會返回到原來的地方,所以一般在子程式使用jmp不會超出本子程式的範圍,否則可能會造成程式跑飛,亂套了。

call(acall,lcall)呼叫中使用了jmp(ajmp,ljmp,sjmp)指令,最後使用ret能不能回到. 這個問題跟我剛才說的一樣。

call(acall,lcall)呼叫前的位置?

這個給你舉例說吧:

.....

mov a,#00h

call loop ;這裡就是call呼叫之前的位置

mov r1,#21h ;這裡是call呼叫之後返回的位置

......

loop:

jc c

mov a,#01h

retcall(acall,lcall)指令中呼叫call(acall,lcall),多少次就會出錯?

這個問題我還沒遇到過,一般在call中繼續用call呼叫子程式不會出什麼錯誤,除非你做的地址有重複,或者使用的暫存器有衝突,或者堆疊沒有設計好,才會出錯的,

我的回答基本就這些,這是第一次給別人回答,這些都是我自己的理解,因為我剛學的時候也遇到過類似的問題,不知道能不能對你有所幫助。

17樓:匿名使用者

進入中斷程式 後,執行reti,程式 轉回進入中斷子程式之前的位置。如果 用了jmp跳轉走了,回不回到原處,很難說了。

18樓:張庚

組合語言的這種跳轉指令最直接了,跟著順一遍就ok了一般是呼叫後,ret回主程式,這個的原理在於在call的時候,自動的把當前程式執行的位置存入堆疊,等於執行了一個push,ret的時候自動出站,把地址吐出來並跳到該位置

中斷程式的reti和ret的不同在於它還涉及開關中斷允許標誌樓主自己可以推斷一下,只要你jmp出去還在ret之前jmp回來,沒有影響到該狀態下的堆疊順序就ok可以。這個常見的,當你的子程式或者中斷程式裡有判斷分支的時候,常常會用判斷性的跳轉語句

微控制器相對很接近硬體,只要把它各個指令執行的原理理清了,這個小東西怎麼工作的,就可以靈活的利用組合語言來控制了

怎樣51微控制器呼叫兩個子程式,怎樣51微控制器呼叫兩個子程式

mov r0,08h mov a,0feh loop mov p1,a lcall del rr a djnz r0,loop 使用djnz 指令。為0執行下一指令,不為0跳轉。就可以呼叫內兩個容子程式了 估計是進入到倒計時程式,一直沒有出來。主程式直接呼叫洗滌程式。定時器,每到1s時,再去呼叫一下...

51微控制器中組合語言如何呼叫c的子程式

我的程式是keil編譯的,如下 先申明extrn code send crc send crc是c中的函式,彙編中加了 呼叫的時候 lcall send crc 如果要專 使用c中的變數,那麼code變成 屬相應的data,xdata等 我的程bai序keil編譯器,extrn code du se...

51微控制器中中斷服務程式佔用時間不

在某種意思上,中 斷更具有實時性,中斷處理是根據程式段的大小花費時間的,中斷程式段如果比定時時間還長,那個這個定時在主程式裡失去意義了 比如中斷定時為10個機器週期,而中斷程式段需要執行11個機器週期,那麼意味著緊著的中斷程式失去了理論的實時性 cpu無法在設計的要求下執行指令,所以,一般情況下,要...