アセンブラで掛け算(乗算) | MUL命令とIMUL命令

足し算、引き算ときて、今回は掛け算をやってみます。
加減算とは異なり、元の数より桁が大きくなる特徴があります。
アセンブラではどのようにレジスタが変化するのでしょうか。

早速コードを書いてみます。




 
 
 


アセンブラでひと桁の掛け算


section .text
global _start

_start:
	mov edx, 0x03
	mov eax, 0x02
	mul edx
	add rax, 0x30
	push rax
	lea rsi, [rsp]
	mov rax, 1
	mov rdi, 1
	mov rdx, 1
	syscall

;改行を出力
	push 0x0a
	lea rsi, [rsp]
	mov rax, 1
	mov rdi, 1
	mov rdx, 1
	syscall

;終了処理
	mov rax, 60
	mov rdi, 0
	syscall

mulというのが掛け算(乗算)を表す命令です。
addやsubとは異なり、オペランドが一つしかありません。

mul rdx
と書けば、
rax = rax × rdx
という意味になります。
※厳密には少し違うのですが後で説明します。

 
 
 


レジスタのサイズ

mul命令の説明の前にレジスタのサイズの説明をします。
x86には様々なレジスタが存在しますが、
そのレジスタの指定方法は以下の図のようになっています。

これはraxレジスタに16進数の0123456789abcdefを格納した状態です。

mov rax, 0x0123456789abcdef
という命令後の状態と思って下さい。

raxレジスタは64bit(8byte)です。
eaxには、下位32bit(4byte)である
0x89abcdef
が格納されています。

同じように
ax : cdef
ah : cd
al : ef
が格納されています。
 
 
 



mul命令とレジスタサイズ

mul命令ではオペランドのサイズによって、
参照元のレジスタと
計算結果を保存するレジスタが変わります。

参照元のレジスタとはraxやeaxのことです。

<オペランドのサイズ>
バイト   … 参照元=al, 保存先=ax
ワード   … 参照元=ax, 保存先=dx:ax
ダブルワード… 参照元=eax, 保存先=edx:eax

例) mul dx
この場合dxのサイズはワードであるため、
参照元のレジスタはax、保存先のレジスタはdx:axということになります。
ここでdx:axとは上位2バイトがdxレジスタに、下位2バイトがaxレジスタに
格納されるという意味です。

掛け算では元の数の桁より、計算結果の桁が大きくなるため、
上位の計算結果を別のレジスタに保存して対応しているようです。

ちなみに2バイト×2バイトの掛け算で4バイトを超えることはないのでしょうか。
2バイトの最大値をかけ合わせてみます。
FF × FF = FE01
問題なく4バイトのサイズに収まっています。

 
 
 


アセンブラで符号付き掛け算(乗算)

次は符号付き掛け算をやってみます。
符号付き掛け算はimul命令で行います。
mul命令とは異なり、オペランドが1〜3の3種類があります。

一つずつ説明していきます。
・オペランドが1つ
imul dx
のように書き、参照元のレジスタ、計算結果の保存先レジスタは
mul命令と全く同じです。

・オペランドが2つ
imul ax, dx
のように書き、
第一オペランド×第二オペランドの結果を
第一オペランドに指定したレジスタに格納します。

イメージとしては
ax = ax * dx
のような感じです。

オペランドが2つの場合、
計算結果が、格納先のレジスタサイズを超えることがあります。
この場合、切り捨てられてから格納されます。

例えば
ax = 0x7FFF
dx = 0xFF
の場合、
0x7FFF * 0xFF = 7F7F01
となりますが、格納先のレジスタサイズが16bitであるため
ax = 7F01が格納されます。
この場合、キャリーフラグと
オーバーフローフラグがセットされるようです。

・オペランドが3つ
mul ax, bx, dx
のように使います。

第二オペランドと第三オペランドの掛け算の計算結果を
第一オペランドに格納します。
つまり、
ax = bx * dx
のようなイメージです。




【関連記事】
アセンブラで加算(足し算) | ADD命令とADC命令の違い、キャリーフラグとオーバーフローフラグの違い
2の補数と引き算(減算)
減算(引き算)でのキャリーフラグの変化 | SUB命令とSBB命令の違い
アセンブラで割り算(除算) | DIV命令とIDIV命令

 
 
新品も中古も激安PC勢ぞろい!パソコン買うなら楽天市場

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です