條件跳轉指令 383

2021-06-06 03:07:55 字數 4483 閱讀 4212

7.5 條件跳轉指令 383 

2006-6-29 15:00:00

· 7.2 低階控制結構 378

·7.3 語句標號 378

·7.4 無條件控制轉移(jmp) 380

·7.6 「中級」控制結構:jt和jf 386

·7.7 使用組合語言實現通用控制結構 386

·7.8 選擇 386

雖然jmp指令提供了控制轉移,但是它不允許進行任何複雜的判斷。80x86條件跳轉指令提供了這種判斷。條件跳轉指令是建立迴圈和實現其他條件執行語句,如if…endif的基本要素。

條件跳轉指令檢查乙個或多個標誌位,判斷它們是否匹配某個特殊條件(就像setcc指令):如果標誌匹配成功,該指令就將控制轉移到目標位置;如果匹配失敗,cpu忽略該條件跳轉指令而繼續執行下一條指令。一些條件跳轉指令只是簡單測試符號位(sign)、進製位(carry)、溢位位(overflow)、零標誌(zero)位的設定。例如,在執行一條sh1指令後,您需要測試進製標誌,來判斷sh1是否從運算元的高位址位移出一位。類似地,也可以在一條test指令後測試零標誌位,來判斷指定的位是否為1。大多數情況,在cmp指令之後執行條件跳轉指令。cmp指令設定標誌位,以便判斷小於、大於、等於等情況。

條件跳轉指令形式如下:

jcc label;

其中,jcc中的「cc」,必須用表示測試條件型別的字串行替換。這些字元和setcc指令使用的一樣。例如,「js」表示根據符號(sign)標誌是否被置位來決定是否跳轉。乙個典型的js指令如下:

js valueisnegative ;

在這個示例中,如果符號(sign)標誌被置位,則js指令將控制轉移到valueisnegative語句標號處;如果符號標誌清零,則將控制直接轉移給js指令後的指令。

與無條件jmp指令不同,條件跳轉指令不提供間接跳轉的形式。惟一允許的形式是跳轉到程式中某一標號處。條件跳轉指令有乙個限制:目標標號的位置必須在跳轉指令本身附近32768位元組範圍內,這通常對應著8000~32000條機器指令。一般情況下不會超過這種限制。

注意:intel文件為許多條件跳轉指令定義了多種替代名或指令別名。表7-1、7-2和7-3列出了每個指令所有的別名。這些**也列出了表示相反分支的指令。很快您將明白這些相反分支指令的作用。

表7-1 測試標誌位的jcc指令

指 令描 述

條 件別 名

相 反 指 令

jc如果進製位被置位則跳轉

進製標誌=1

jb,jnae

jncjnc

如果進製位沒有置位則跳轉

進製標誌=0

jnb,jae

jcjz

如果0標誌被置位則跳轉

0標誌=1

jejnz

jnz如果0標誌沒有置位則跳轉

0標誌=0

jnejz

(續表)

指 令描 述

條 件別 名

相反指令

js如果符號位被置位則跳轉

符號標誌=1

jnsjns

如果符號位沒有被置位則跳轉

符號標誌=0

jsjo

如果溢位標誌置位則跳轉

溢位標誌=1

jnojno

如果溢位標誌沒有置位則跳轉

溢位標誌=0

jojp

如果奇偶校驗位被置位則跳轉

奇偶校驗標誌=1

jpejnp

jpe如果奇偶校驗位為偶校驗則跳轉

奇偶校驗標誌=1

jpjpo

jnp如果奇偶校驗位沒有被置位則跳轉

奇偶校驗標誌=0

jpojp

jpo如果奇偶校驗位為奇校驗則跳轉

奇偶校驗標誌=0

jnpjpe

表7-2 使用無符號數比較的jcc指令

指 令描 述

條 件別 名

相反指令

ja如果超過(>)則跳轉

進製標誌=0,0標誌=0

jnbe

jnajnbe

如果不低於或等於(不 <=)則跳轉

進製標誌=0,0標誌=0

jajbe

jae如果超過或等於(>=)則跳轉

進製標誌=0

jnc,jnb

jnae

jnb如果不低於則跳轉(不 <)

進製標誌=0

jnc,jae

jbjb

如果低於(<)則跳轉

進製標誌=1

jc,jnae

jnbjnae

如果不超過或等於(不》=)則跳轉

進製標誌=1

jc,jb

jaejbe

如果低於或等於(<=)則跳轉

進製標誌=1或0標誌=1

jnajnbe

jna如果不超過(不》)則跳轉

進製標誌=1或0標誌=1

jbeja

je如果相等(=)則跳轉

0標誌=1

jzjne

jne如果不相等(<>)則跳轉

0標誌=0

jnzje

表7-3 使用有符號數比較的jcc指令

指 令描 述

條 件別 名

相反指令

jg如果大於(>)則跳轉

符號標誌=溢位標誌或0標誌=0

jnle

jngjnle

如果小於或等於(<=)則跳轉

符號標誌=溢位標誌或0標誌=0

jgjle

jge

如果大於或等於(>=)則跳轉

符號標誌=溢位標誌

jnljge

jnl如果不小於(不<)則跳轉

符號標誌=溢位標誌

jge jl

jl 如果小於(<)則跳轉

符號標誌<>溢位標誌

jnge

jnljnge

如果大於或等於(>=)跳轉

符號標誌<>溢位標誌jl

jge

jle如果小於或等於(<=)跳轉

符號標誌<>溢位標誌或0標誌=1

jngjnle

jng如果不大於(不》)則跳轉

符號標誌<>溢位標誌或0標誌=1

jlejg

je如果等於(=)則跳轉

0標誌=1

jzjne

jne如果不等於(<>)則跳轉

0標誌=0

jnzje

接下來將對「相反指令」一列進行簡單的說明。在許多情況下,需要產生與某條分支指令條件相反的分支(在本章後面會給出示例),即相反分支。除了兩個例外,都可以按下面的簡單規則(後面統稱為n/no n規則)產生相反分支:

● 如果jcc的第二個字母不是「n」,則在「j」後面插入乙個「n」。例如:je對應為jne,jl對應為jnl。

● 如果jcc的第二個字母是「n」,則去掉指令中的「n」。例如:jng對應為jg,jne對應為je。

不遵循這兩條規則的兩個例外是jpe(奇偶位為偶跳轉)和jpo(奇偶位為奇跳轉)。這兩個例外並不會導致什麼問題,因為:(a)很少需要測試奇偶標誌;(b)可以使用別名jp和jnp替代jpe和jpo。而「n/no n」規則對jp和jnp是適用的。

雖然jge是jl的相反指令,但是建議使用jnl作為jl的相反指令。因為很容易誤認為「大於是小於的相反」,從而把jg當作jl的相反指令。您可以堅持使用「n/no n」規則以避免這種混淆。

80x86條件跳轉指令提供了這樣的能力:根據判斷條件將程式流分支到兩條路徑中的某一條。例如,要實現:如果bx等於cx,則暫存器ax的值加1。可以使用下面的**來完成該功能:

cmp(bx,cx );

jne skipstmts;

inc(ax );

skipstmts:

其中的訣竅是使用相反分支指令來跳過在條件滿足的情況下需要執行的指令。請堅持使用前面介紹的「n/no n」規則來選擇相反分支指令。

使用條件跳轉指令還可以實現迴圈。例如,下面的**序列實現了從使用者輸入讀入一串字元,並將字元儲存到一組連續的單元中,直到使用者輸入回車鍵。

mov(0,edi );

rdlnloop:

stdin.getc(); //read a character into the al register.

mov(al,input [edi])); //store away the character.

inc(edi ); //move on to the next character.

cmp(al,stdio.cr ); //see if the user pressed enter.

jne rdlnloop;

與setcc指令類似,條件跳轉指令分為兩類—— 測試特殊處理器標誌位的條件跳轉指令(例如jz、jc、jno)和測試某些條件(小於、大於等)的條件跳轉指令。當測試某個條件時,條件跳轉指令通常緊跟在乙個cmp指令之後。cmp指令設定標誌位後,如果是無符號數比較,使用ja、jae、jb、jbe、je或jne等指令測試這些標誌來判斷是否小於、小於等於、等於、不等於、大於或大於等於;如果是有符號數比較,則使用jl、jle、je、jne、jg、jge指令。

條件跳轉指令測試標誌位,但不影響標誌位。

014 無條件跳轉指令jmp

l無條件跳轉指令 jmp lgoto 指令 l 優化後的指令 l標誌暫存器 psw 1514 1312 111098 7654 3210 ofdf iftf sfzf afpfcf零 標誌標誌暫存器psw 程式狀態字暫存器 psw 標誌暫存器psw是乙個16為的暫存器。它反映了cpu運算的狀態特徵並...

組合語言條件跳轉指令彙總

x86 指令集包含大量的條件跳轉指令。它們能比較有符號和無符號整數,並根據單個 cpu 標誌位的值來執行操作。條件跳轉指令可以分為四個型別 基於特定標誌位的值跳轉 基於兩數是否相等,或是否等於 e cx 的值跳轉 基於無符號運算元的比較跳轉 基於有符號運算元的比較跳轉 下表展示了基於零標誌位 進製標...

組合語言條件跳轉指令詳解

指令 解釋jz 如果zf 1,跳轉至指定位置 jnz如果zf 0,跳轉至制定位置 je與jz類似,但通常在一條cmp指令後使用。如果源運算元與目的運算元相等,則跳轉 jne與jnz類似,但通常在一條cmp指令後使用。如果源運算元與目的運算元不相等,則跳轉 jgcmp指令做有符號比較之後,如果目的運算...