有條件的跳躍
根據標誌的狀態,CPU 可以執行或忽略跳轉。基於標誌執行跳轉的指令屬於 Jcc 的通用名稱 - 條件程式碼 1 上的跳轉。
同義詞和術語
為了提高彙編程式碼的可讀性,英特爾為相同的條件程式碼定義了幾個同義詞。例如,jae
,jnb
和 jnc
都是相同的條件程式碼 CF = 0 。
雖然指令名稱可能會對何時使用它給出非常強烈的暗示,但唯一有意義的方法是識別需要測試的標誌然後適當地選擇指令。
然而,英特爾給出了在 cmp
指令之後使用時非常有意義的指令名稱。出於本討論的目的,假設 cmp
在條件跳轉之前設定了標誌。
相等
如果設定了 *ZF,*則運算元相等,否則它們不同。為了測試相等性,我們需要 ZF = 1 。
je a_label ;Jump if operands are equal
jz a_label ;Jump if zero (Synonym)
jne a_label ;Jump if operands are NOT equal
jnz a_label ;Jump if not zero (Synonym)
指令 | 標誌 |
---|---|
je ,jz |
ZF = 1 |
jne ,jnz |
ZF = 0 |
比…更棒
對於無符號運算元,如果不需要進位,則目標大於源,即 CF = 0 時。當 CF = 0 時,運算元可能相等,測試 ZF 將消除歧義。
jae a_label ;Jump if above or equal (>=)
jnc a_label ;Jump if not carry (Synonym)
jnb a_label ;Jump if not below (Synonym)
ja a_label ;Jump if above (>)
jnbe a_label ;Jump if not below and not equal (Synonym)
指令 | 標誌 |
---|---|
jae ,jnc ,jnb |
CF = 0 |
ja ,jnbe |
CF = 0,ZF = 0 |
對於帶**符號的運算元,**我們需要檢查 SF = 0 ,除非有符號溢位,在這種情況下產生的 SF 反轉。由於 *OF = 0,*如果沒有發生簽名溢位,否則為 1,我們需要檢查 SF = OF 。
ZF 可用於實施嚴格/非嚴格測試。
jge a_label ;Jump if greater or equal (>=)
jnl a_label ;Jump if not less (Synonym)
jg a_label ;Jump if greater (>)
jnle a_label ;Jump if not less and not equal (Synonym)
指令 | 標誌 |
---|---|
jge ,jnl |
SF = OF |
jg ,jnle |
SF = OF,ZF = 0 |
少於
這些使用上述的反轉條件。
jbe a_label ;Jump if below or equal (<=)
jna a_label ;Jump if not above (Synonym)
jb a_label ;Jump if below (<)
jc a_label ;Jump if carry (Synonym)
jnae a_label ;Jump if not above and not equal (Synonym)
;SIGNED
jle a_label ;Jump if less or equal (<=)
jng a_label ;Jump if not greater (Synonym)
jl a_label ;Jump if less (<)
jnge a_label ;Jump if not greater and not equal (Synonym)
指令 | 標誌 |
---|---|
jbe ,jna |
CF = 1 或 ZF = 1 |
jb ,jc ,jnae |
CF = 1 |
jle ,jng |
SF != OF 或 ZF = 1 |
jl ,jnge |
SF != OF |
具體標誌
可以使用 j<flag_name>
單獨測試每個標誌,其中 flag_name 不包含尾隨 F (例如 CF → C , PF → P )。
以前未涉及的其餘程式碼是:
指令 | 標誌 |
---|---|
js |
SF = 1 |
jns |
SF = 0 |
jo |
OF = 1 |
jno |
OF = 0 |
jp ,jpe (e = even) |
PF = 1 |
jnp ,jpo (o = odd) |
PF = 0 |
還有一個條件跳轉(額外的一個)
一個特殊的 x86 條件跳轉不會測試標誌。相反,它測試 cx
或 ecx
暫存器的值(基於當前 CPU 地址模式為 16 或 32 位),並且當暫存器包含零時執行跳轉。
該指令設計用於在類似於 rep
的指令之前或者在 loop
迴圈之前驗證計數器暫存器(cx/ecx
)。
jcxz a_label ; jump if cx (16b mode) or ecx (32b mode) is zero
jecxz a_label ; synonym of jcxz (recommended in source code for 32b target)
指令 | 註冊(不是標誌) |
---|---|
jcxz ,jecxz |
cx = 0(16b 模式) |
jcxz ,jecxz |
ecx = 0(32b 模式) |
1 或類似的東西。