<li id="8g3ty"><tbody id="8g3ty"><th id="8g3ty"></th></tbody></li>
    <label id="8g3ty"><samp id="8g3ty"></samp></label>
  • <span id="8g3ty"></span>

    1. <center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
    2. <bdo id="8g3ty"><meter id="8g3ty"><bdo id="8g3ty"></bdo></meter></bdo><center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
      <label id="8g3ty"><samp id="8g3ty"></samp></label>

    3. 電子開發網

      電子開發網電子設計 | 電子開發網Rss 2.0 會員中心 會員注冊
      搜索: 您現在的位置: 電子開發網 >> 電子開發 >> 單片機 >> 正文

      51單片機指令系統:控制轉移類指令(8)

      作者:佚名    文章來源:網絡    點擊數:    更新時間:2008/11/4
      第二十六課:控制轉移類指令分析
      控制轉移指令用于控制程序的流向,所控制的范圍即為程序存儲器區間,MCS-51系列單片機的控制轉移指令相對豐富,有可對64kB程序空間地址單元進行訪問的長調用、長轉移指令,也有可對2kB字節進行訪問的絕對調用和絕對轉移指令,還有在一頁范圍內短相對轉移及其它無條件轉移指令,這些指令的執行一般都不會對標志位有影響。

      [1]. 無條件轉移指令(4條)
      這組指令執行完后,程序就會無條件轉移到指令所指向的地址上去。長轉移指令訪問的程序存儲器空間為16地址64kB,絕對轉移指令訪問的程序存儲器空間為11位地址2kB空間。

      LJMP  addr16     ;addr16→(PC),給程序計數器賦予新值(16位地址)

      AJMP  addr11     ;(PC)+2→(PC),addr11→(PC10-0)程序計數器賦予新值(11位地址),(PC15-11)不改變

      SJMP  rel         ;(PC)+ 2 + rel→(PC)當前程序計數器先加上2再加上偏移量給程序計數器賦予新值

      JMP  @A+DPTR   ;(A)+ (DPTR)→(PC),累加器所指向地址單元的值加上數據指針的值給程序計數器賦予新值

      這幾條指令,如果要他細分析的話,區別較大,但初學者時,可以不理會那么多,統統理解成LJMP標號,也就是跳轉到一個標號處,但事實上,JMP標號,在前面的例程中我們已接觸過,并且也知道如何來使用了,AJMP和SJMP也是一樣,那么這幾條指令它們的區別何在呢?在于跳轉的范圍不一樣。好比跳遠,LJMP一下就能跳64K那么遠(當然近了就更沒關系了)。而AJMP最多只能跳2K距離,而SJMP則最多只能跳256這么遠,原則上,所有用AJMP或SJMP的地方都可以用LJMP來替代。因此在初學者時,需要跳轉時可以全用LJMP。

      但是在查表時要注意會出錯,因為他們的機器周期不一樣,取得的數也不一樣。

      [2]. 條件轉移指令(8條)
      條件轉移指令是指在滿足一定條件時進行相對轉移

      JZ  rel               ; A=0,(PC)+ 2 + rel→(PC),累加器中的內容為0,則轉移到偏移量所指向的地址,否則程序往下執行

      JNZ  rel              ; A≠0,(PC)+ 2 + rel→(PC),累加器中的內容不為0,則轉移到偏移量所指向的地址,否則程序往下執行

      這兩條指令是判斷A內容是否為0轉移指令
      第一條指令的功能是:如果(A)=0,則轉移,否則順序執行(執行本指令的下一條指令)。轉移到什么地方去呢?如果按照傳統的方法,就要算偏移量,很麻煩,好在現在我們可以借助機器匯編了,因此這條指令我們可以這樣理解:
      JB  標號
      即轉移到標號處,下面舉一例說明:
         MOV  A,R0
         JZ   L1
         MOV  R1,#00H
         AJMP L2
      L1:MOV  R1,#0FFH
      L2:SJMP L2
         END
      在執行上面這段程序前,如果R0中的值是0的話,就轉移到L1執行,因此最終的執行結果是R1中的值為0FFH。而如果R0中的值不等于0,則順序執行,也就是執行MOV  R1,#00H指令。最終的執行結果是R1中的值等于0。
      第一條指令的功能清楚了,第二條當然就好理解了,如果A中的值不等于0,就轉移。把上面的例子中的JZ改成JNZ試試看,程序執行的結果是怎樣的?

      CJNE  A, data, rel     ; A≠(data),(PC)+ 3 + rel→(PC),累加器中的內容不等于直接地址單元的內容,則轉移到偏移量所指向的地址,否則程序往下執行

      CJNE  A, #data, rel    ; A≠#data,(PC)+ 3 + rel→(PC),累加器中的內容不等于立即數,則轉移到偏移量所指向的地址,否則程序往下執行

      CJNE  Rn, #data, rel  ; A≠#data,(PC)+ 3 + rel→(PC),工作寄存器Rn中的內容不等于立即數,則轉移到偏移量所指向的地址,否則程序往下執行

      CJNE  @Ri, #data, rel ; A≠#data,(PC)+ 3 + rel→(PC),工作寄存器Ri指向地址單元中的內容不等于立即數,則轉移到偏移量所指向的地址,否則程序往下執行

      第一條指令的功能是將A中的值和立即數data比較,如果兩者相等,就順序執行(執行程序的下一條指令),如果不相等,就轉移,同樣的,我們可以將rel理解成標號。即CJNE  A,#data,標號。這樣利用這條指令,我們就可以判斷兩數是否相等,這在很多場合是非常有用的。但有時還想得知兩數比較后哪個大,哪個小。本條指令也具有這樣的功能,如果兩數不相等,則CPU還會反映出哪個數大,哪個數小,這是用CY(進位位)來實現的。如果前面的數(A中的)大,則CY=0,否則CY=1,因此在程序轉移后再次利用CY就可判斷出A中的數比data大還是小了。
      例:
         MOV  A,R0
         CJNE A,#10H,L1
         MOV  R1,#0FFH
         AJMP L3
      L1:JC   L2
         MOV  R1,#0AAH
         AJMP L3
      L2:MOV  R1,#0FFH
      L3:SJMP L3
      上面的程序中有一條指令我們還沒學過,即JC,這條指令的原型是JC  rel,作用我上面的JZ類似,但是它是判斷CY是0,還是1進行轉移,如果CY=1,則轉移到JC后面的標號處執行,如果CY=0則順序執行(執行它的下面的一條指令)。
      分析一下上面的程序,如果(A)=10H,則順序執行,即R1=0。如果(A)不等于10H,則轉到L1處繼續執行,在L1處,再次進行判斷,如果(A)大于10H,則CY=1,將順序執行,即MOV  R1,#0AAH指令,而如果(A)小于10H,則將轉移到L2處運行,即執行MOV  R1,#0FFH指令。
      因此最終結果是:本程序執行前,如果(R0)=10H,則(R1)=00H,如果(R0)大于10H,則(R1)=0AAH,如果(R0)小于10H,則(R1)=0FFH。
      弄懂了這條指令,其它的幾條就類似了,第二條是把A當中的值和直接地址的中的值比較,第三條則是將直接地址中的值和立即數比較,第四條是將間址尋址得到的數和立即數比較,這里就不詳談了,下面給出幾個相應的例子。
      CJNE  A,10H   ;把A中的值和10H中的值比較(注意和前面題目的區別)
      CJNE  10H,#35H;把10H中的值和35H中的值比較
      CJNE  @R0,#35H;把R0中的值作為地址,從此地址中取數并和35H比較。

      DJNZ  Rn, rel ; (Rn)-1→(Rn),(Rn)≠0,(PC)+ 2 + rel→(PC)工作寄存器Rn減1不等于0,則轉移到偏移量所指向的地址,否則程序往下執行

      DJNZ  data, rel ; (Rn)-1→(Rn),(Rn)≠0,(PC)+ 2 + rel→(PC)直接地址單元中的內容減1不等于0,則轉移到偏移量所指向的地址,否則程序往下執行

      這兩條指令在前面我們已有提到,這里就不多說了。

      [3]. 子程序調用指令(1條)
      子程序是為了便于程序編寫,減少那些需反復執行的程序占用多余的地址空間而引入的程序分支,從而有了主程序和子程序的概念,需要反復執行的一些程序,我們在編程時一般都把它們編寫成子程序,當需要用它們時,就用一個調用命令使程序按調用的地址去執行,這就需要子程序的調用指令和返回指令。

      LCALL  addr16 ; 長調用指令,可在64kB空間調用子程序。此時(PC)+ 3→(PC),(SP)+ 1→(SP),(PC7-0)→(SP),(SP)+ 1→(SP),(PC15-8)→(SP),addr16→(PC),即分別從堆棧中彈出調用子程序時壓入的返回地址

      ACALL  addr11 ; 絕對調用指令,可在2kB空間調用子程序,此時(PC)+ 2→(PC),(SP)+ 1→(SP),(PC7-0)→(SP),(SP)+ 1→(SP),(PC15-8)→(SP),addr11→(PC10-0)

      上面這兩條指令就是在主程序中調用子程序的。

      RET  ; 子程序返回指令。此時(SP)→(PC15-8),(SP)- 1→(SP),(SP)→(PC7-0),(SP)- 1→(SP)

      子程序返回指令
      子程序執行完后必須回到主程序,如何返回呢?只要執行一條返回指令就可以了,即執行RET。


      RETI  ; 中斷返回指令,除具有RET功能外,還具有恢復中斷邏輯的功能,需注意的是,RETI指令不能用RET代替

      [4]. 空操作指令(1條)
      所謂空操作,就是什么也不做,停一個周期,一般用作短時間的延時。

      NOP     ; 這條指令除了使PC加1,消耗一個機器周期外,沒有執行任何操作。可用于短時間的延時
      Tags:單片機,指令,控制轉移  
      責任編輯:admin
      相關文章列表
      沒有相關文章
      請文明參與討論,禁止漫罵攻擊,不要惡意評論、違禁詞語。 昵稱:
      1分 2分 3分 4分 5分

      還可以輸入 200 個字
      [ 查看全部 ] 網友評論
      關于我們 - 聯系我們 - 廣告服務 - 友情鏈接 - 網站地圖 - 版權聲明 - 在線幫助 - 文章列表
      返回頂部
      刷新頁面
      下到頁底
      晶體管查詢
      主站蜘蛛池模板: 亚洲欧洲综合在线| 亚洲AⅤ优女AV综合久久久| 亚洲乱码中文字幕综合234| 香蕉久久综合精品首页| 激情综合亚洲色婷婷五月APP| 色综合热无码热国产| 亚洲综合无码AV一区二区 | 区三区激情福利综合中文字幕在线一区亚洲视频1 | 伊人婷婷综合缴情亚洲五月| 亚洲综合伊人制服丝袜美腿| 久久婷婷色综合一区二区| 色综合色综合久久综合频道| 国产精品亚洲综合一区| 亚洲精品综合久久中文字幕| 99精品国产综合久久久久五月天 | 天天综合天天添夜夜添狠狠添| 国产综合色在线视频区| 日日狠狠久久偷偷色综合0| 亚洲综合无码一区二区痴汉| 狼狼综合久久久久综合网| 综合久久给合久久狠狠狠97色| 色综合天天综合网国产国产人| 伊人色综合一区二区三区影院视频| 日本一道综合色视频| 综合国产在线观看无码| 日韩人妻无码一区二区三区综合部 | 成人综合伊人五月婷久久| 一本久久综合亚洲鲁鲁五月天| 狠狠色伊人亚洲综合网站色| 亚洲国产精品综合久久久| 97色婷婷成人综合在线观看| 久久精品亚洲综合一品| 久久精品亚洲综合| 久久综合国产乱子伦精品免费| 色欲香天天天综合网站| 一本久久a久久精品综合夜夜| 久久伊人久久亚洲综合| 久久亚洲精品人成综合网| 99久久亚洲综合精品成人网| 亚洲欧美日韩综合久久久久| 色先锋资源久久综合5566|