X86アセンブラ/算術演算命令

出典: フリー教科書『ウィキブックス(Wikibooks)』
移動先: 案内検索

算術演算命令[編集]

算術演算命令は、 2 つのオペランドを取る。デスティネーション (転送先) とソース (転送元) である。 デスティネーションは、レジスターか、メモリーでの位置でなくてはならない。 ソースは、メモリーでの位置、レジスター、定数のどれかでなくてはならない。 二つのうち少なくとも一つは、レジスターでなくてはならない。 操作は、ソースとデスティネーションの両方を、メモリーでの位置にすることはできないためである。


add src, dest GAS文法
add dest, src MASM文法

この命令は、srcdestに加算する。 MASN や NASM の文法を使う場合には、結果は最初の引数に格納される。 GAS の文法を使う場合には、結果は 2 番目の引数に格納される。


sub src, dest GAS文法
sub dest, src MASM文法

この命令は ADD と同じようであるが、デスティネーションからソースを減算する。

mul arg

この命令は「arg」に A レジスターのバイト長に応じた値を乗算する。 下表を参照のこと。

オペランドのサイズ 1 バイト 2 バイト 4 バイト
その他のオペランド AL AX EAX
結果の上位部分の格納先 AH DX EDX
結果の下位部分の格納先 AL AX EAX

2 番目の場合、古いプロセッサー向けに書かれたコードとの後方互換性のため、ターゲットは EAX ではない。


imul arg

MUL と同じであるが、符号付き数値のみを扱う。


div arg

この命令は、レジスターの内容を「arg」で除算する。 下表を参照のこと。

除数のサイズ 1 バイト 2 バイト 4 バイト
被除数 AX DX:AX EDX:EAX
剰余の格納先 AH DX EDX
商の格納先 AL AX EAX

%eax が設定されていれば、「cltd (MASM の文法では CDQ)」を使うことで、%edx を用意できる。

 cltd
 idiv   %ebx, %eax

商が商の格納先レジスターに合わなかった場合、数値オーバーフロー例外が発生する。 操作の後、全てのフラグは未定義の状態になる。

idiv arg

DIV と同じであるが、符号付き数値のみを扱う。

neg arg

引数の符号を算術的に反転させる。つまり 2 の補数を取る。


キャリーあり算術演算命令[編集]

adc src, dest GAS文法
adc dest, src MASM文法

キャリーあり加算。 destsrc + キャリーフラグを加算し、結果をdestに格納する。 通常、加算命令でレジスターの 2 倍の長さの値を扱うのを助ける。 以下の例では、sourceは 64 ビットの数値であり、destinationに加算される。

mov eax, [source] ; read low 32 bits
mov edx, [source+4] ; read high 32 bits
add [destination], eax ; add low 32 bits
adc [destination+4], edx ; add high 32 bits, plus carry


sbb src, dest GAS文法
sbb dest, src MASM文法

ボローあり減算。 src + キャリーフラグdestから減算し、結果をdestに格納する。 通常、減算命令でレジスターの 2 倍の長さの値を扱うのを助ける。

インクリメントとデクリメント[編集]

inc arg

引数のレジスターの値を 1 ずつインクリメントする。 ADD arg, 1よりずっと早く動作する。

dec arg

引数のレジスターの値を 1 ずつデクリメントする。

ポインターの算術演算[編集]

lea 命令は、算術演算にも使うことができ、特にポインターの算術演算に使われる。 アドレス計算命令を参照のこと。