接下來(lái)將對(duì)“相反指令”一列進(jìn)行簡(jiǎn)單的說(shuō)明。在許多情況下,需要產(chǎn)生與某條分支指令條件相反的分支(在本章后面會(huì)給出示例),即相反分支。除了兩個(gè)例外,都可以按下面的簡(jiǎn)單規(guī)則(后面統(tǒng)稱為N/No N規(guī)則)產(chǎn)生相反分支: ● 如果Jcc的第二個(gè)字母不是“n”,則在“j”后面插入一個(gè)“n”。例如:je對(duì)應(yīng)為jne,jl對(duì)應(yīng)為jnl。 ● 如果Jcc的第二個(gè)字母是“n”,則去掉指令中的“n”。例如:jng對(duì)應(yīng)為jg,jne對(duì)應(yīng)為je。 不遵循這兩條規(guī)則的兩個(gè)例外是jpe(奇偶位為偶跳轉(zhuǎn))和jpo(奇偶位為奇跳轉(zhuǎn))。這兩個(gè)例外并不會(huì)導(dǎo)致什么問(wèn)題,因?yàn)?#xff1a;(a)很少需要測(cè)試奇偶標(biāo)志;(b)可以使用別名jp和jnp替代jpe和jpo。而“N/No N”規(guī)則對(duì)jp和jnp是適用的。 雖然jge是jl的相反指令,但是建議使用jnl作為jl的相反指令。因?yàn)楹苋菀渍`認(rèn)為“大于是小于的相反”,從而把jg當(dāng)作jl的相反指令。您可以堅(jiān)持使用“N/No N”規(guī)則以避免這種混淆。 80x86條件跳轉(zhuǎn)指令提供了這樣的能力:根據(jù)判斷條件將程序流分支到兩條路徑中的某一條。例如,要實(shí)現(xiàn):如果BX等于CX,則寄存器AX的值加1。可以使用下面的代碼來(lái)完成該功能: cmp(bx,cx ); jne SkipStmts; inc(ax ); SkipStmts: 其中的訣竅是使用相反分支指令來(lái)跳過(guò)在條件滿足的情況下需要執(zhí)行的指令。請(qǐng)堅(jiān)持使用前面介紹的“N/no N”規(guī)則來(lái)選擇相反分支指令。 使用條件跳轉(zhuǎn)指令還可以實(shí)現(xiàn)循環(huán)。例如,下面的代碼序列實(shí)現(xiàn)了從用戶輸入讀入一串字符,并將字符存儲(chǔ)到一組連續(xù)的單元中,直到用戶輸入回車鍵。 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指令類似,條件跳轉(zhuǎn)指令分為兩類—— 測(cè)試特殊處理器標(biāo)志位的條件跳轉(zhuǎn)指令(例如jz、jc、jno)和測(cè)試某些條件(小于、大于等)的條件跳轉(zhuǎn)指令。當(dāng)測(cè)試某個(gè)條件時(shí),條件跳轉(zhuǎn)指令通常緊跟在一個(gè)cmp指令之后。cmp指令設(shè)置標(biāo)志位后,如果是無(wú)符號(hào)數(shù)比較,使用ja、jae、jb、jbe、je或jne等指令測(cè)試這些標(biāo)志來(lái)判斷是否小于、小于等于、等于、不等于、大于或大于等于;如果是有符號(hào)數(shù)比較,則使用jl、jle、je、jne、jg、jge指令。 條件跳轉(zhuǎn)指令測(cè)試標(biāo)志位,但不影響標(biāo)志位。