新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 8086指令系統(tǒng)---控制轉(zhuǎn)移指令(二)

8086指令系統(tǒng)---控制轉(zhuǎn)移指令(二)

作者: 時間:2016-11-27 來源:網(wǎng)絡(luò) 收藏
  3 循環(huán)指令


  這一組指令在循環(huán)結(jié)構(gòu)的程序中用來控制一段程序(稱為循環(huán)體)的重復(fù)執(zhí)行,在匯編指令中循環(huán)的轉(zhuǎn)向地址用標(biāo)號來表示,而在機器指令中給出的是位移量,所以執(zhí)行循環(huán)指令時,若滿足循環(huán)條件,CPU就計算轉(zhuǎn)向地址:(IP)當(dāng)前+8位位移量→(IP),即實現(xiàn)循環(huán)。

  若不滿足循環(huán)條件,即退出循環(huán),程序繼續(xù)順序執(zhí)行。
  循環(huán)指令都是短轉(zhuǎn)移格式的指令,也就是說,位移量是用8位帶符號數(shù)來表示的,轉(zhuǎn)向地址在相對于當(dāng)前IP值的-128 ~ +127字節(jié)范圍之內(nèi)。

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

  在多重循環(huán)的程序結(jié)構(gòu)中,如果各層循環(huán)都使用循環(huán)指令來控制,則應(yīng)注意對CX中循環(huán)計數(shù)值的保存與恢復(fù)。
循環(huán)指令均不影響條件碼。

本文引用地址:http://butianyuan.cn/article/201611/322187.htm

  LOOP  label    循環(huán)(loop)
  執(zhí)行操作:① (CX)←(CX)-1
       ② 若(CX)≠0,則(IP)←(IP)當(dāng)前+位移量,否則循環(huán)結(jié)束

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

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

例編寫程序,實現(xiàn)兩個數(shù)據(jù)塊BLOCK1和BLOCK2相加,結(jié)果存入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 子程序調(diào)用與返回指令

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

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

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

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

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

  ● CALL FAR PTR SUBROUT 段間直接調(diào)用
  執(zhí)行操作:① (SP) ← (SP)-2,((SP)) ← (CS)當(dāng)前
         (SP) ← (SP)-2,((SP)) ← (IP)當(dāng)前
      ?、?(IP) ← 偏移地址(在指令的第2、3個字節(jié)中)
         (CS) ← 段地址(在指令的第4、5個字節(jié)中)

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

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

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

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

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

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

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

  帶立即數(shù)返回指令,除完成偏移地址出?;蚱频刂泛投蔚刂烦鰲5牟僮魍?,還要再使SP的內(nèi)容加上一個立即數(shù)N,使堆棧指針SP移動到新的位置。指令中的N可以是一個常數(shù),也可以是一個表達式。帶立即數(shù)返回指令適用于C或PASCAL的調(diào)用規(guī)則,這些規(guī)則在調(diào)用過程(子程序)前先把參數(shù)壓入堆棧,子程序使用這些參數(shù)后,如果在返回時丟棄這些已無用的參數(shù),就在RET指令中包含一個數(shù)字,它表示壓入到堆棧中參數(shù)的字節(jié)數(shù),這樣堆棧指針就恢復(fù)到參數(shù)入棧前的值。

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

 例根據(jù)下面調(diào)用程序和子程序的程序清單,畫出RET指令執(zhí)行前和執(zhí)行后的堆棧情況。假設(shè)初始的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指令將數(shù)據(jù)30和40壓入堆棧,CALL指令執(zhí)行后,返回地址000B又壓入堆棧,緊接著程序控制轉(zhuǎn)移到子程序ADDM。子程序中的PUSH指令又使BP的值進棧,此時SP指向棧頂0FFA。MOV指令將0FFA傳送給BP,使BP作為尋址堆棧數(shù)據(jù)的指針。(BP+4)指向的是40,(BP+6)指向的是30,取出數(shù)據(jù)后用POP指令恢復(fù)了BP原先的值,此時,(SP)=0FFC,這是RET 4指令執(zhí)行前的堆棧狀態(tài)。


上一頁 1 2 下一頁

評論


技術(shù)專區(qū)

關(guān)閉