分岐命令
分岐命令は命令ポインタ(RIP)を書き換えることでプログラムの実行位置を変更します。数値の比較と比較結果で動作が変わる条件分岐命令、条件転送命令等があります。
JMP
プリフィックス | オペコード | 命令 | 説明 |
---|---|---|---|
- | EB cb | JMP rel8 | jmp命令の次の命令のアドレス ±127 バイトの範囲で分岐する。 |
- | E9 cd | JMP rel32 | jmp命令の次の命令のアドレス ±2G バイトの範囲で分岐する。 |
- | FF /4 | JMP r/m64 | レジスタまたはメモリで指定された 64 ビットのオフセットへ分岐する。 |
プリフィックス | オペコード | 命令 | 説明 |
---|---|---|---|
- | FF /5 | JMP m16:16 | m16:16 で指定されるアドレスに絶対間接分岐する。 |
- | FF /5 | JMP m16:32 | m16:32 で指定されるアドレスに絶対間接分岐する。 |
REX.W | FF /5 | JMP m16:64 | 64 ビットモードの場合、セレクタの指示先がゲートであれば、 RIP は64 ビットのディスプレースメントであり、ゲートから取得される。 指示先がゲートでなければ、RIP はゼロ拡張された32 ビットのオフセットであり、 命令で参照されるfar ポインタから取得される。 |
- | EB cb | JMP rel8 | Jump short, RIP = RIP + 8-bit displacement sign extended to 64-bits |
- | E9 cd | JMP rel32 | Jump near, relative, RIP = RIP + 32-bit displacement sign extended to 64-bits |
- | FF /4 | JMP r/m64 | Jump near, absolute indirect, RIP = 64-Bit offset from register or memory |
- | FF /5 | JMP m16:16 | Jump far, absolute indirect, address given in m16:16 |
- | FF /5 | JMP m16:32 | Jump far, absolute indirect, address given in m16:32. |
REX.W | FF /5 | JMP m16:64 | Jump far, absolute indirect, address given in m16:64. |
JECXZ / JRCXZ
ECX または RCX の値が 0 の場合に、次の命令のアドレス ±127 バイトの範囲で分岐します。
プリフィックス | オペコード | 命令 | 説明 |
---|---|---|---|
67 | E3 cb | JECXZ rel8 | ECX が 0 なら分岐 |
- | E3 cb | JRCXZ rel8 | RCX が 0 なら分岐 |
LOOP / LOOPZ / LOOPNZ
RCXをカウンタとして使い、RCXの値をデクリメント(1を減じる)し、カウント≠0 の場合に、次の命令のアドレス ±127 バイトの範囲で分岐します。繰り返し回数をRCXレジスタに設定し、繰り返す部分の最後にLOOP命令を置き、RCXが 0 でなければ先頭に戻る(分岐)ことで繰り返し回数の決まっているループを構成するために使います。LOOPZ、LOOPNZ命令はカウンタが 0 でない場合にゼロフラグがゼロ(LOOPZ)またはゼロでない(LOOPNZ)場合に分岐します。loop命令より dec/jnz の組み合わせのほうが速いためloop命令はあまり使われません。以下のコードはどちらも100回繰り返されます。
mov rcx, 100 mov rcx, 100 label01: label01: 繰り返し部分 繰り返し部分 pushf loop label01 dec rcx popf jrcxz label01
プリフィックス | オペコード | 命令 | 説明 |
---|---|---|---|
- | E2 cb | LOOP rel8 | RCXをデクリメントし、カウント≠0 の場合に 8bitオフセットで分岐する。 |
REX.W | E2 cb | LOOP rel8 | RCXをデクリメントし、カウント≠0 の場合に 8bitオフセットで分岐する。JMP Shortでは、RIP = RIP + 64 ビットに符号拡張された8 ビットのオフセット。 |
- | E1 cb | LOOPE rel8 | RCXをデクリメントし、カウント≠0 でかつZF=1 の場合に 8bitオフセットで分岐する。 |
REX.W | E1 cb | LOOPE rel8 | RCXをデクリメントし、カウント≠0 でかつZF=1 の場合に 8bitオフセットで分岐する。JMP Short では、RIP = RIP + 64ビットに符号拡張された8 ビットのオフセット。 |
- | E0 cb | LOOPNE rel8 | RCXをデクリメントし、カウント≠0 でかつZF=0 の場合に 8bitオフセットで分岐する。 |
REX.W | E0 cb | LOOPNZ rel8 | RCXをデクリメントし、カウント≠0 でかつZF=0 の場合に 8bitオフセットで分岐する。JMP Short では、RIP = RIP + 64ビットに符号拡張された8 ビットのオフセット。 |
条件フラグの名称と意味
条件分岐命令、条件転送命令のオペコードに含まれている、条件を表す名称は以下の表のように 30種類が割り当てられています。「大きくない」と「小さいか等しい」と同じ状態を表す名称が 重複して使用できるようになっています。また逆の意味をもつ条件を対応させると9種類の 正逆2種類となって、かなり覚えやすくなると思います。Jcc、CMOVcc、SETcc で90種類ある 命令を 3命令 x 9条件 x 正逆2つ として分解して理解すると楽になります。
正 | | 逆 | ||||
---|---|---|---|---|---|---|
名称 | 別名 | 意味 | 名称 | 別名 | 意味 | |
Z Zero |
E Equal |
等しい/ゼロ (ZF=1) |
NZ NotZero |
NE NotEqual |
等しくない/ゼロでない (ZF=0)) |
|
A Above |
NBE NotBelow or Equal |
符号なしで大きい (CF=0 および ZF=0) |
BE Below or Equal |
NA NotAbove |
符号なしで小さいか等しい (CF=1 または ZF=1) |
|
B Below |
NAE NotAbove or Equal |
符号なしで小さい (CF=1) |
AE Above or Equal |
NB NotBelow |
符号なしで大きいか等しい (CF=0) |
|
G Greater |
NLE NotLess or Equal |
大きい (ZF=0 および SF=OF) |
LE Less or Equal |
NG NotGreater |
小さいか等しい (ZF=1 または SF<>OF) |
|
L Less |
NGE NotGreater or Equal |
小さい (SF<>OF) |
GE Greater or Equal |
NL NotLess |
大きいか等しい (SF=OF) |
|
P Parity |
PE ParityEven |
パリティが偶数 (PF=1) |
NP NotParity |
PO ParityOdd |
パリティが奇数 (PF=0) |
|
C Carry |
キャリー (CF=1) |
NC NotCarry |
キャリークリア (CF=0) |
|||
O Overflow |
オーバーフロー (OF=1) |
NO NotOverflow |
オーバーフローでない (OF=0) |
|||
S Sign |
2の補数で負、 最上位ビットが1(SF=1) |
NS NotSign |
2の補数で正、 最上位ビットが0(SF=0) |
条件分岐命令(Jcc)
プリフィックス | オペコード | 命令 | 説明 |
---|---|---|---|
- | 74 cb | JZ rel8 | ゼロの場合に分岐する。 |
- | 0F 84 cd | JZ rel32 | |
- | 75 cb | JNZ rel8 | ゼロでない場合に分岐する。 |
- | 0F 85 cd | JNZ rel32 | |
- | 77 cb | JA rel8 | 符号なしで大きい場合に分岐する。 |
- | 0F 87 cd | JA rel32 | |
- | 76 cb | JBE rel8 | 符号なしで小さいか等しい場合に分岐する。 |
- | 0F 86 cd | JBE rel32 | |
- | 72 cb | JB rel8 | 符号なしで小さい場合に分岐する。 |
- | 0F 82 cd | JB rel32 | |
- | 73 cb | JAE rel8 | 符号なしで大きいか等しい場合に分岐する。 |
- | 0F 83 cd | JAE rel32 | |
- | 7F cb | JG rel8 | 大きい場合に分岐する。 |
- | 0F 8F cd | JG rel32 | |
- | 7E cb | JLE rel8 | 小さいか等しい場合に分岐する。 |
- | 0F 8E cd | JLE rel32 | |
- | 7C cb | JL rel8 | 小さい場合に分岐する。 |
- | 0F 8C cd | JL rel32 | |
- | 7D cb | JGE rel8 | 大きいか等しい場合に分岐する。 |
- | 0F 8D cd | JGE rel32 | |
- | 7A cb | JP rel8 | パリティが偶数の場合に分岐する。 |
- | 0F 8A cd | JP rel32 | |
- | 7B cb | JNP rel8 | パリティが奇数の場合に分岐する。 |
- | 0F 8B cd | JNP rel32 | |
- | 72 cb | JC rel8 | キャリーがある場合に分岐する。 |
- | 0F 82 cd | JC rel32 | |
- | 73 cb | JNC rel8 | キャリーがない場合に分岐する。 |
- | 0F 83 cd | JNC rel32 | |
- | 70 cb | JO rel8 | オーバーフローがある場合に分岐する。 |
- | 0F 80 cd | JO rel32 | |
- | 71 cb | JNO rel8 | オーバーフローがない場合に分岐する。 |
- | 0F 81 cd | JNO rel32 | |
- | 78 cb | JS rel8 | 2の補数で負の場合に分岐する。 |
- | 0F 88 cd | JS rel32 | |
- | 79 cb | JNS rel8 | 2の補数で正の場合に分岐する。 |
- | 0F 89 cd | JNS rel32 |
フラグの変化 : 変化しない。
フラグ | OF | SF | ZF | AF | CF | PF |
---|---|---|---|---|---|---|
実行後 | - | - | - | - | - | - |
条件転送命令 (CMOVcc)
プリフィックス | オペコード | 命令 | 説明 |
---|---|---|---|
66 | 0F 44 /r | CMOVZ r16, r/m16 | ゼロの場合にコピーする。 |
- | 0F 44 /r | CMOVZ r32, r/m32 | |
REX.W | 0F 44 /r | CMOVZ r64, r/m64 | |
66 | 0F 45 /r | CMOVNZ r16, r/m16 | ゼロでない場合にコピーする。 |
- | 0F 45 /r | CMOVNZ r32, r/m32 | |
REX.W | 0F 45 /r | CMOVNZ r64, r/m64 | |
66 | 0F 47 /r | CMOVA r16, r/m16 | 符号なしで大きい場合にコピーする。 |
- | 0F 47 /r | CMOVA r32, r/m32 | |
REX.W | 0F 47 /r | CMOVA r64, r/m64 | |
66 | 0F 46 /r | CMOVBE r16, r/m16 | 符号なしで小さいか等しい場合にコピーする。 |
- | 0F 46 /r | CMOVBE r32, r/m32 | |
REX.W | 0F 46 /r | CMOVBE r64, r/m64 | |
66 | 0F 42 /r | CMOVB r16, r/m16 | 符号なしで小さい場合にコピーする。 |
- | 0F 42 /r | CMOVB r32, r/m32 | |
REX.W | 0F 42 /r | CMOVB r64, r/m64 | |
66 | 0F 43 /r | CMOVAE r16, r/m16 | 符号なしで大きいか等しい場合にコピーする。 |
- | 0F 43 /r | CMOVAE r32, r/m32 | |
REX.W | 0F 43 /r | CMOVAE r64, r/m64 | |
66 | 0F 4F /r | CMOVG r16, r/m16 | 大きい場合にコピーする。 |
- | 0F 4F /r | CMOVG r32, r/m32 | |
REX.W | 0F 4F /r | CMOVG r64, r/m64 | |
66 | 0F 4E /r | CMOVLE r16, r/m16 | 小さいか等しい場合にコピーする。 |
- | 0F 4E /r | CMOVLE r32, r/m32 | |
REX.W | 0F 4E /r | CMOVLE r64, r/m64 | |
66 | 0F 4C /r | CMOVL r16, r/m16 | 小さい場合にコピーする。 |
- | 0F 4C /r | CMOVL r32, r/m32 | |
REX.W | 0F 4C /r | CMOVL r64, r/m64 | |
66 | 0F 4D /r | CMOVGE r16, r/m16 | 大きいか等しい場合にコピーする。 |
- | 0F 4D /r | CMOVGE r32, r/m32 | |
REX.W | 0F 4D /r | CMOVGE r64, r/m64 | |
66 | 0F 4A /r | CMOVP r16, r/m16 | パリティが偶数の場合にコピーする。 |
- | 0F 4A /r | CMOVP r32, r/m32 | |
REX.W | 0F 4A /r | CMOVP r64, r/m64 | |
66 | 0F 4B /r | CMOVNP r16, r/m16 | パリティが奇数の場合にコピーする。 |
- | 0F 4B /r | CMOVNP r32, r/m32 | |
REX.W | 0F 4B /r | CMOVNP r64, r/m64 | |
66 | 0F 42 /r | CMOVC r16, r/m16 | キャリーがある場合にコピーする。 |
- | 0F 42 /r | CMOVC r32, r/m32 | |
REX.W | 0F 42 /r | CMOVC r64, r/m64 | |
66 | 0F 43 /r | CMOVNC r16, r/m16 | キャリーがない場合にコピーする。 |
- | 0F 43 /r | CMOVNC r32, r/m32 | |
REX.W | 0F 43 /r | CMOVNC r64, r/m64 | |
66 | 0F 40 /r | CMOVO r16, r/m16 | オーバーフローがある場合にコピーする。 |
- | 0F 40 /r | CMOVO r32, r/m32 | |
REX.W | 0F 40 /r | CMOVO r64, r/m64 | |
66 | 0F 41 /r | CMOVNO r16, r/m16 | オーバーフローがない場合にコピーする。 |
- | 0F 41 /r | CMOVNO r32, r/m32 | |
REX.W | 0F 41 /r | CMOVNO r64, r/m64 | |
66 | 0F 48 /r | CMOVS r16, r/m16 | 2の補数で負の場合にコピーする。 |
- | 0F 48 /r | CMOVS r32, r/m32 | |
REX.W | 0F 48 /r | CMOVS r64, r/m64 | |
66 | 0F 49 /r | CMOVNS r16, r/m16 | 2の補数で正の場合にコピーする。 |
- | 0F 49 /r | CMOVNS r32, r/m32 | |
REX.W | 0F 49 /r | CMOVNS r64, r/m64 |
フラグの変化 : 変化しない。
フラグ | OF | SF | ZF | AF | CF | PF |
---|---|---|---|---|---|---|
実行後 | - | - | - | - | - | - |
条件セット命令 (SETcc)
条件フラグにしたがってレジスタ、またはメモリ(バイト) に 1 を設定する。
プリフィックス | オペコード | 命令 | 説明 |
---|---|---|---|
- | 0F 94 | SETZ r/m8 | ゼロの場合に 1 を格納する。 |
REX | 0F 94 | SETZ r/m8 | |
- | 0F 95 | SETNZ r/m8 | ゼロでない場合に 1 を格納する。 |
REX | 0F 95 | SETNZ r/m8 | |
- | 0F 97 | SETA r/m8 | 符号なしで大きい場合に 1 を格納する。 |
REX | 0F 97 | SETA r/m8 | |
- | 0F 96 | SETBE r/m8 | 符号なしで小さいか等しい場合に 1 を格納する。 |
REX | 0F 96 | SETBE r/m8 | |
- | 0F 92 | SETB r/m8 | 符号なしで小さい場合に 1 を格納する。 |
REX | 0F 92 | SETB r/m8 | |
- | 0F 93 | SETAE r/m8 | 符号なしで大きいか等しい場合に 1 を格納する。 |
REX | 0F 93 | SETAE r/m8 | |
- | 0F 9F | SETG r/m8 | 大きい場合に 1 を格納する。 |
REX | 0F 9F | SETG r/m8 | |
- | 0F 9E | SETLE r/m8 | 小さいか等しいの場合に 1 を格納する。 |
REX | 0F 9E | SETLE r/m8 | |
- | 0F 9C | SETL r/m8 | 小さい場合に 1 を格納する。 |
REX | 0F 9C | SETL r/m8 | |
- | 0F 9D | SETGE r/m8 | 大きいか等しい場合に 1 を格納する。 |
REX | 0F 9D | SETGE r/m8 | |
- | 0F 9A | SETP r/m8 | パリティが偶数の場合に 1 を格納する。 |
REX | 0F 9A | SETP r/m8 | |
- | 0F 9B | SETNP r/m8 | パリティが奇数の場合に 1 を格納する。 |
REX | 0F 9B | SETNP r/m8 | |
- | 0F 92 | SETC r/m8 | キャリーがある場合に 1 を格納する。 |
REX | 0F 92 | SETC r/m8 | |
- | 0F 93 | SETNC r/m8 | キャリーがない場合に 1 を格納する。 |
REX | 0F 93 | SETNC r/m8 | |
- | 0F 90 | SETO r/m8 | オーバーフローがある場合に 1 を格納する。 |
REX | 0F 90 | SETO r/m8 | |
- | 0F 91 | SETNO r/m8 | オーバーフローがない場合に 1 を格納する。 |
REX | 0F 91 | SETNO r/m8 | |
- | 0F 98 | SETS r/m8 | 2の補数で負の場合に 1 を格納する。 |
REX | 0F 98 | SETS r/m8 | |
- | 0F 99 | SETNS r/m8 | 2の補数で正の場合に 1 を格納する。 |
REX | 0F 99 | SETNS r/m8 |
フラグの変化 : 変化しない。
フラグ | OF | SF | ZF | AF | CF | PF |
---|---|---|---|---|---|---|
実行後 | - | - | - | - | - | - |