新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 8086指令系統---控制轉移指令(二)

        8086指令系統---控制轉移指令(二)

        作者: 時間:2016-11-27 來源:網絡 收藏
          3 循環指令


          這一組指令在循環結構的程序中用來控制一段程序(稱為循環體)的重復執行,在匯編指令中循環的轉向地址用標號來表示,而在機器指令中給出的是位移量,所以執行循環指令時,若滿足循環條件,CPU就計算轉向地址:(IP)當前+8位位移量→(IP),即實現循環。

          若不滿足循環條件,即退出循環,程序繼續順序執行。
          循環指令都是短轉移格式的指令,也就是說,位移量是用8位帶符號數來表示的,轉向地址在相對于當前IP值的-128 ~ +127字節范圍之內。

          對條件循環指令LOOPZ(LOOPE)和LOOPNZ(LOOPNE),除測試CX中的循環次數外,還將ZF的值作為循環的必要條件,因此,要注意將條件循環指令緊接在形成ZF的指令之后。

          在多重循環的程序結構中,如果各層循環都使用循環指令來控制,則應注意對CX中循環計數值的保存與恢復。
        循環指令均不影響條件碼。

        本文引用地址:http://www.104case.com/article/201611/322187.htm

          LOOP  label    循環(loop)
          執行操作:① (CX)←(CX)-1
              ?、?若(CX)≠0,則(IP)←(IP)當前+位移量,否則循環結束

          LOOPZ/LOOPE label 為零/相等時循環(loop while zero,or equal)
          執行操作:① (CX)←(CX)-1
              ?、?若ZF=1且(CX)≠0,則(IP)←(IP)當前+位移量,否則循環結束

          LOOPNZ/LOOPNE label 不為零/不等時循環(loop while nonzero,or not equal)
          執行操作:① (CX)←(CX)-1
              ?、?若ZF=0且(CX)≠0,則(IP)←(IP)當前+位移量,否則循環結束

        例編寫程序,實現兩個數據塊BLOCK1和BLOCK2相加,結果存入BLOCK2。
               DATA   SEGMENT
               BLOCK1   DW   100 DUP(?)
               BLOCK2   DW   100 DUP(?)
               DATA  ENDS
               ; - - - - - - - - - - - - - - - - - -
               CODE   SEGMENT
               ASSUME CS:CODE,DS:DATA,ES:DATA
            START:MOV   AX,DATA
               MOV   DS,AX        ; initialize the data segment
               MOV   ES,AX        ; initialize the extra segment
               CLD             ; DF=0 for autoincrement
               MOV   CX,100        ; load the counter
               MOV   SI,OFFSET BLOCK1  ; address of block1
               MOV   DI,OFFSET BLOCK2  ; address of block2
            NEXT: LODSW            ; load the data of block1 into AX
               ADD   AX,ES:[DI]     ; add the data of block2 to AX
               STOSW            ; store the sum to block2
               LOOP   NEXT        ; repeat 100 times
               MOV   AX,4C00H      ; return to DOS
               INT   21H
            CODE  ENDS
               END   START

         4 子程序調用與返回指令

          子程序是一種非常重要的計算機編程結構,它存儲在存儲器中,可供一個或多個調用程序(主程序)反復調用。主程序調用子程序時使用CALL指令,由子程序返回主程序時使用RET指令。由于調用程序和子程序可以在同一個代碼段中,也可以在不同的代碼段中,因此,CALL指令和RET指令也有近調用、近返回及遠調用、遠返回兩類格式。

        ?、?CALL NEAR PTR SUBPROUT 近調用(near call)
          近調用是CALL指令的缺省格式,可以寫為"CALL subrotine"。它調用同一個代碼段內的子程序(子過程),因此,在調用過程中不用改變CS的值,只需將子程序的地址存入IP寄存器。CALL指令中的調用地址可以用直接和間接兩種尋址方式表示。

        ?、?CALL FAR PTR SUBPROUT 遠調用(far call)
          遠調用適用于調用程序(也稱為主程序)和子程序不在同一段中的情況,所以也叫做段間調用。和近調用指令一樣,遠調用指令中的尋址方式也可用直接方式和間接方式。

         ⑶ RET 返回指令(return)
          RET指令執行的操作是把保存在堆棧中的返回地址出棧,以完成從子程序返回到調用程序的功能。

          ● CALL SUBROUT 段內直接調用
          執行操作:① (SP) ← (SP)-2,((SP)) ← (IP)當前
               ② (IP) ← (IP)當前+16位位移量(在指令的第2、3個字節中)
          
          ● CALL DESTIN 段內間接調用
          執行操作:① (SP) ← (SP)-2,((SP)) ← (IP)當前
              ?、?(IP) ← (EA) ; (EA)為指令尋址方式所確定的有效地址

          ● CALL FAR PTR SUBROUT 段間直接調用
          執行操作:① (SP) ← (SP)-2,((SP)) ← (CS)當前
                 (SP) ← (SP)-2,((SP)) ← (IP)當前
               ② (IP) ← 偏移地址(在指令的第2、3個字節中)
                 (CS) ← 段地址(在指令的第4、5個字節中)

          ● CALL WORD PTR DESTIN 段間間接調用
          執行操作:① (SP) ← (SP)-2,((SP)) ← (CS)當前
                 (SP) ← (SP)-2,((SP)) ← (IP)當前
               ② (IP) ← (EA) ; (EA)為指令尋址方式所確定的有效地址
                 (CS) ← (EA+2)

          從CALL指令執行的操作可以看出,第一步是把子程序返回調用程序的地址保存在堆棧中。對段內調用,只需將IP的當前值,即CALL指令的下一條指令的地址存入SP所指示的堆棧字單元中。對段間調用,保存返回地址則意味著要將CS和IP的當前值分別存入堆棧的兩個字單元中。

          CALL指令的第二步操作是轉子程序,即把子程序的入口地址交給IP(段內調用)或CS:IP(段間調用)。對段內直接方式,調轉的位移量,即子程序的入口地址和返回地址之間的差值就在機器指令的2、3字節中。對段間直接方式,子程序的偏移地址和段地址就在操作碼之后的兩個字中。對間接方式,子程序的入口地址就從尋址方式所確定的有效地址中獲得。

          ● RET 段內返回(近返回)
          執行操作:(IP) ← ((SP)),(SP) ← (SP)+2

          ● RET 段間返回(遠返回)
          執行操作:(IP) ← ((SP)),(SP) ← (SP)+2
               (CS) ←((SP)),(SP) ← (SP)+2

          ● RET N 帶立即數返回
          執行操作:① 返回地址出棧(操作同段內或段間返回)
              ?、?修改堆棧指針:(SP) ← (SP)+N

          子程序的最后一條指令必須是RET指令,以返回到主程序。如果是段內返回,只需把保存在堆棧中的偏移地址出棧存入IP即可,如果是段間返回,則要把偏移地址和段地址都從堆棧中取出送到IP和CS寄存器中。

          帶立即數返回指令,除完成偏移地址出棧或偏移地址和段地址出棧的操作外,還要再使SP的內容加上一個立即數N,使堆棧指針SP移動到新的位置。指令中的N可以是一個常數,也可以是一個表達式。帶立即數返回指令適用于C或PASCAL的調用規則,這些規則在調用過程(子程序)前先把參數壓入堆棧,子程序使用這些參數后,如果在返回時丟棄這些已無用的參數,就在RET指令中包含一個數字,它表示壓入到堆棧中參數的字節數,這樣堆棧指針就恢復到參數入棧前的值。

          CALL指令和RET指令都不影響條件碼。

         例根據下面調用程序和子程序的程序清單,畫出RET指令執行前和執行后的堆棧情況。假設初始的SS:SP=A000:1000。
         
            0000  B8 001E   MOV  AX,30
            0003  BB 0028   MOV  BX,40
            0006  50      PUSH AX     ; push data1 into stack
            0007  53      PUSH BX     ; push data2 into stack
            0008  E8 0066   CALL ADDM    ; call subroutine
            000B  B4 02    MOV  AH,2
            …   …      …
            0071  ADDM     PROC NEAR  ; entry point (IP)←0071=000b+0066
            0071  55      PUSH BP     ; save BP
            0072  8B E4    MOV  BP,SP    ; addressing the stack with BP
            0074  8B 46 04  MOV  AX,[BP+4] ; get data2 from stack
            0077  03 46 06   ADD  AX,[BP+6] ; add data1
            007A  CD      POP  BP     ; get back BP
            007B  C2      0004 RET 4   ; return and revert SP
            007E  ADDM     ENDP

        圖 CALL指令和RET指令對堆棧的影響



          如圖3.12所示,主程序中的兩條PUSH指令將數據30和40壓入堆棧,CALL指令執行后,返回地址000B又壓入堆棧,緊接著程序控制轉移到子程序ADDM。子程序中的PUSH指令又使BP的值進棧,此時SP指向棧頂0FFA。MOV指令將0FFA傳送給BP,使BP作為尋址堆棧數據的指針。(BP+4)指向的是40,(BP+6)指向的是30,取出數據后用POP指令恢復了BP原先的值,此時,(SP)=0FFC,這是RET 4指令執行前的堆棧狀態。


        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 普定县| 宜州市| 娄底市| 井冈山市| 溧阳市| 朝阳市| 马尔康县| 南城县| 石泉县| 阿坝| 酒泉市| 调兵山市| 桂林市| 武定县| 原阳县| 威海市| 浮梁县| 闽侯县| 尚义县| 祥云县| 花莲县| 蓝山县| 托克托县| 赤峰市| 高邮市| 四子王旗| 马鞍山市| 额敏县| 沂水县| 武功县| 根河市| 县级市| 黎城县| 德阳市| 迁安市| 克什克腾旗| 万全县| 界首市| 南城县| 怀宁县| 枞阳县|