1. 程式人生 > >組合語言--微機CPU的指令系統(五)(轉移指令)

組合語言--微機CPU的指令系統(五)(轉移指令)

(9)轉移指令

轉移指令是組合語言程式設計師經常使用的一組指令。在高階語言中,時常有“儘量不要使用轉移語句”的勸告,但如果在組合語言的程式中也儘量不用轉移語句,那麼該程式要麼無法編寫,要麼沒有多少功能,所以,在組合語言中,不但要使用轉移指令,而且還要靈活運用,因為指令系統中有大量的轉移指令。

轉移指令分無條件轉移指令和有條件轉移指令兩大類。

1、無條件轉移指令(Transfer Unconditionally)

無條件轉移指令包括:JMP、子程式的呼叫和返回指令、中斷的呼叫和返回指令等。

下面只介紹無條件轉移指令JMP(Unconditional Jump)。

JMP指令的一般形式:

JMP 標號/Reg/Mem

JMP指令是從程式當前執行的地方無條件轉移到另一個地方執行。這種轉移可以是一個短(short)轉移(偏移量在[-128, 127]範圍內),近(near)轉移(偏移量在[-32K, 32K]範圍內)或遠(far)轉移(在不同的程式碼段之間轉移)。

短和近轉移是段內轉移,JMP指令只把目標指令位置的偏移量賦值指令指標暫存器IP,從而實現轉移功能。但遠轉移是段間轉移,JMP指令不僅會改變指令指標暫存器IP的值,而且還會改變程式碼段暫存器CS的值。

該轉移指令的執行不影響任何標誌位。

例如:

next1: …

JMP next1 ;向前轉移,偏移量之差為負數

JMP next2 ;向後轉移,偏移量之差為正數

next2: …

在目前流行的彙編系統中,當段內轉移時,有些軟體把該轉移指令預設為近轉移,從而使指令的偏移量用一個字來表示,於是生成3個位元組的指令程式碼,但如果程式設計師自己清楚轉移的幅度在一個短轉移的範圍之內,那麼,可用前置short的辦法來告訴彙編程式,讓它產生2個位元組的指令程式碼。

比如:如果程式設計師知道在上例中的標號next2離“JMP next2”指令的偏移量不會超過127,那麼,可用下面的轉移方式來省掉一個位元組的指令程式碼。

next2: …

JMP short next2 ;生成2個位元組的轉移指令,從而節省一個位元組

2、條件轉移指令(Transfer Conditionally)

條件轉移指令是一組極其重要的轉移指令,它根據標誌暫存器中的一個(或多個)標誌位來決定是否需要轉移,這就為實現多功能程式提供了必要的手段。微機的指令系統提供了豐富的條件轉移指令來滿足各種不同的轉移需要,在程式設計序時,要對它們靈活運用。

條件轉移指令又分三大類:基於無符號數的條件轉移指令、基於有符號數的條件轉移指令和基於特殊算術標誌位的條件轉移指令。

(a) 無符號數的條件轉移指令(Jumps Based on Unsigned (Logic) Data)

clip_image002

(b) 有符號數的條件轉移指令(Jumps Based on Signed (Arithmetic) Data)

clip_image004

(c) 特殊算術標誌位的條件轉移指令(Jumps Based on Special Arithmetic Tests)

clip_image006

例5.15 編寫一程式段,它把暫存器AX-BX的絕對值存入BX中。

解:

SUB BX, AX

JNS next

NEG BX

next: …

例5.16 已知一個位元組變數char,試編寫一程式段,把其所存的大寫字母變成小寫字母。

解:

char DB 'F' ;變數說明

MOV AL, char

CMP AL, 'A'

JB next ;注意:字元是無符號數,不要使用指令JL

CMP AL, 'Z'

JA next

ADD char, 20H ;小寫字母比大寫字母的ASCII碼大20H

next: …

如果不知道(或忘了)大小寫字母ASCII碼之間的關係,那麼,可用數值表示式'a'-'A'、'b'-'B'、…、'z'-'Z'等來代替具體的數值20H。

例5.17 編寫一段程式,完成下面計算公式,其中:變數X和Y都是字型別。

解:

X DW ? ;變數說明

Y DW ?

MOV AX, X

MOV BX, AX ;用BX來臨時存放計算結果

CMP AX, 0

JLE setdata

CMP AX, 500

JG case3

ADD BX, 100D ;BX=X+100

JMP setdata

next: SUB BX, 50D ;BX=X-50

setdata: MOV Y, BX ;把計算結果賦給變數Y

例5.18 下面迴圈體的指令程式碼位元組數超過128,試改寫該迴圈。

MOV CX, COUNT ;給迴圈計數器賦初值(>0)

again: 迴圈體指令序列 ;迴圈體的首地址偏移量大於128

LOOP again

解:

MOV CX, COUNT

again: 迴圈體指令序列

DEC CX

JNZ again ;把LOOP指令改為條件轉移指令