サーチ…


無条件ジャンプ

jmp a_label                      ;Jump to a_label
jmp bx                           ;Jump to address in BX
jmp WORD [aPointer]              ;Jump to address in aPointer
jmp 7c0h:0000h                   ;Jump to segment 7c0h and offset 0000h
jmp FAR WORD [aFarPointer]       ;Jump to segment:offset in aFarPointer

相対的な近点ジャンプ

jmp a_labelは次のjmp a_labelです。

  • 近く
    宛先の論理アドレスのオフセット部分のみを指定します。セグメントはCSと仮定する。
  • 相対
    命令セマンティックは、次の命令アドレスまたはIP = IP + relからジャンプrelバイト1を転送します。

命令は、 EB <rel8>またはEB <rel16/32>いずれかとしてエンコードされます。アセンブラは、最も適切な形式を選択します。
例えばNASM jmp SHORT a_labeljmp WORD a_labeljmp DWORD a_labelなどのアセンブラオーバーライドが可能です。

絶対間接近点ジャンプ

jmp bxjmp WORD [aPointer]は次のとおりです。

  • 近く
    これらは、宛先の論理アドレスのオフセット部分のみを指定します。セグメントはCSと仮定する。
  • 絶対間接
    命令の意味は、 regまたはmemのアドレス、またはIP = regIP = memジャンプします。

命令はFF /4として符号化され、間接的にはオペランドのサイズは他のすべてのメモリアクセスについて決定される。

絶対遠いジャンプ

jmp 7c0h:0000hは:

  • 遠い
    論理アドレスの両方の部分、セグメントとオフセットを指定します。

  • absolute命令のセマンティックは、アドレスセグメント:offsetまたはCS = segment, IP = offsetジャンプします。

命令は、コードサイズに応じてEA <imm32/48>としてエンコードされます。
いくつかのアセンブラで2つの形式の中から選択することができます。例えば、NASM jmp 7c0h: WORD 0000hjmp 7c0h: DWORD 0000hは第1と第2の形式を生成します。

絶対間接遠距離ジャンプ

jmp FAR WORD [aFarPointer]は次のとおりです。

  • farこれは、 論理アドレスの両方の部分、つまりセグメントとオフセットを指定します。

  • Absolute indirect命令の意味は、 mem 2またはCS = mem[23:16/32], IP = [15/31:0]格納されているセグメント:オフセットにジャンプします。

命令はFF /5として符号化され、オペランドのサイズはサイズ指定子を有するコントローラとすることができる。
NASMでは直感的ではありませんが、 16:16オペランドの場合はjmp FAR WORD [aFarPointer]16:32オペランドの場合はjmp FAR DWORD [aFarPointer]です。


行方不明のジャンプ

  • 近くの絶対
    間接的に近いジャンプでエミュレートできます。

      mov bx, target            ;BX = absolute address of target
      jmp bx
    
  • 遠い親戚
    とにかく使用感が無く、狭すぎます。


1 2つの補数を使用して、符号付きオフセットを指定し、したがって後方にジャンプします。
2サイズ16:1616:32の seg16:off16またはseg16:off32になります。

試験条件

条件ジャンプを使用するには、条件をテストする必要があります。ここでの条件のテストは 、フラグをチェックする行為のみを参照し、実際のジャンプは条件ジャンプで説明します。

x86は、EFLAGSレジスタに頼って条件をテストします。EFLAGSレジスタは、各命令が設定できるフラグのセットを保持します。

subaddような算術命令andxorandなどの論理命令は明らかに「フラグを設定する」。これは、フラグCFOFSFZFAFPFがそれらの命令によって変更されることを意味する。どの命令でもフラグを変更することができます。たとえば、 cmpxchgZFを変更します。

特定の命令によってどのフラグが変更されているかを知るには、命令参照常にチェックしてください。

x86には、以前に言及した一連の条件付きジャンプがあり 、一部のフラグが設定されているか、一部がクリアまたはその両方である場合にのみジャンプします。


フラグ

算術演算と論理演算は、フラグの設定に非常に便利です。たとえば、 sub eax, ebxというsub eax, ebx後で、今度は符号なしの値を保持しているとします。

設定時クリア時
ZF 結果がゼロの場合。
EAX - EBX = 0⇒EAX = EBX
結果がゼロでない場合。
EAX - EBX≠0⇒EAX≠EBX
CF 結果がMSbのために運ぶ必要があったとき。
EAX - EBX <0⇒EAX <EBX
結果がMSbのためにキャリーを必要としなかったとき。
EAX - EBX≮0⇒EAX≮EBX
SF 結果MSbがセットされたとき。 結果MSbがセットされていない場合。
署名付きオーバーフローが発生したとき。 署名付きオーバーフローが発生しなかったとき。
PF 結果の最下位バイトに設定されているビット数が偶数の場合。 結果の最下位バイトに設定されたビット数が奇数の場合。
AF 下位のBCD桁がキャリーを生成したとき。
それはビット4のキャリーです。
下BCD桁はキャリーを生成しなかったとき。
それはビット4のキャリーです。

非破壊検査

subおよびand命令は、デスティネーションオペランドを変更し、デスティネーションを変更しないように2つの余分なコピー(セーブおよびリストア)を必要とします。

非破壊テストを実行するには、 cmptestという命令がありtest操作の結果が破棄され、フラグのみが保存されることを除いて、それらは破壊的な対応と同じです。

破壊的な非破壊的
sub cmp
and test

test eax, eax             ;and eax, eax
                          ;ZF = 1 iff EAX is zero

test eax, 03h             ;and eax, 03h
                          ;ZF = 1 if both bit[1:0] are clear
                          ;ZF = 0 if at least one of bit[1:0] is set

cmp eax, 241d             ;sub eax, 241d
                          ;ZF = 1 iff EAX is 241
                          ;CF = 1 iff EAX < 241

署名付きおよび無署名テスト

CPUは値1を登録するための特別な意味を与えません。signはプログラマの構造体です。 符号付きおよび符号なしの値をテストするときに違いはありません。プロセッサは、オペランドが符号付きおよび符号なしとみなされる場合は、通常の算術関係(等しい、より小さい、より大きいなど)をテストするのに十分なフラグを計算します。


1 2の補数のような特定のフォーマットでしか意味をなさない命令がいくつかありますが、これは、ソフトウェアでのアルゴリズムの実装に多くのコードが必要となるため、コードをより効率的にするためです。

条件付きジャンプ

フラグの状態に基づいて、CPUはジャンプを実行または無視することができます。フラグに基づいてジャンプを実行する命令は、 Jcc - Jump on Condition Code 1という一般名の下にあります。

同義語と用語

アセンブリコードの読みやすさを向上させるために、インテルは同じ条件コードに対していくつかの同義語を定義しました。たとえば、 jaejnb 、および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)
命令フラグ
jejz ZF = 1
jnejnz 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)
命令フラグ
jaejncjnb CF = 0
jajnbe 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)
命令フラグ
jgejnl SF = OF
jgjnle 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)
命令フラグ
jbejna CF = 1またはZF = 1
jbjcjnae CF = 1
jlejng SF!= OFまたはZF = 1
jljnge SF!= OF

特定のフラグ

各フラグは、 j<flag_name>で個別にテストできます.flag_nameには後続のFCFCPFPなど )が含まれていません。

前に説明しなかった残りのコードは次のとおりです。

命令
js SF = 1
jns SF = 0
jo OF = 1
jno OF = 0
jpjpe (e =偶数) PF = 1
jnpjpo (o =奇数) PF = 0

1つの条件付きジャンプ(余分なもの)

特別なx86条件ジャンプの1つでは、フラグをテストしません。代わりに、現在のCPUアドレスモードが16または32ビットであるcxまたはecxレジスタのテスト値を実行し、レジスタがゼロを含むときにジャンプが実行されます。

この命令は、 カウンタレジスタ (の検証のために設計されたcx/ecx )前方のrep様の命令、又は前方のloopループ。

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)
命令レジスタ(フラグではない)
jcxzjecxz cx = 0(16bモード)
jcxzjecxz ecx = 0(32bモード)

1そういうものか。

算術関係をテストする

符号なし整数

より大きい

cmp eax, ebx
ja a_label  

それ以上

cmp eax, ebx
jae a_label  

未満

cmp eax, ebx
jb a_label  

以下

cmp eax, ebx
jbe a_label 

等しい

cmp eax, ebx
je a_label 

等しくない

cmp eax, ebx
jne a_label     

符号付き整数

より大きい

cmp eax, ebx
jg a_label  

それ以上

cmp eax, ebx
jge a_label  

未満

cmp eax, ebx
jl a_label  

以下

cmp eax, ebx
jle a_label 

等しい

cmp eax, ebx
je a_label 

等しくない

cmp eax, ebx
jne a_label 

a_label

上記の例では、 a_labelは、テストされた条件が "true"の場合のCPUのターゲット先です。テストされた条件が "偽"の場合、CPUは条件ジャンプに続く次の命令を続行します。

類義語

命令のシノニムは、コードの可読性を向上させるために使用できます。
例えば、 jajnbe (Jump non jnbe equal)は同じ命令です。

署名付きのコンパニオンコード

操作署名なし署名された
> ja jg
> = jae jge
< jb jl
<= jbe jle
= je je
≠、!=、<> jne jne


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow