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無法在設計的要求下執行指令,所以,一般情況下,要...