Linuxでx86アセンブラ（四則演算編）

# \:large_blue_diamond:この記事について
アセンブラでのプログラミングに必要な知識を少しずつ書いていきます．
名づけて「Linuxでx86アセンブラ」シリーズ．今回は３回目です．
前回の記事は応用に関する物事でした．今回は基礎に立ち戻りアセンブラでの四則演算の計算方法を書いていきたいと思います．

# 使用するソフトウェア
この連載ではLinux環境でnasmを使用することを想定しています．

# \:large_blue_diamond:ニーモニックとオペランド
アセンブリのコードは主にニーモニックとオペランドで構成されます．
ニーモニックはCPUが、実行できる命令です．オペランドは、実行する命令の操作対象です．

![オペランドとニーモニック](https://qiita-image-store.s3.amazonaws.com/0/77676/a9ab1d38-3ef4-2197-071d-56dc9bcdddbc.png)

上の例だと、`eax`と`10`がオペランドで、`mov`がニーモニックです．
`mov`ニーモニックは、レジスタとメモリ、または既定値の間のデータの移動を行う命令です．この命令ではeaxレジスタに10進数の10を代入しています．
アセンブリでは主に2種類の記述方法があります．一つはIntel記法、もうひとつはAT&T記法です．２つの記法は主にオペランドの順序に違いがあります．Intel記法では右側が元になるオペランドで、左側が行き先のオペランドです．AT&Tはその逆です．下の例の場合、Intel記法ではeaxレジスタにebxレジスタの内容を代入します．AT&T記法ではebxレジスタにeaxレジスタの内容を代入します．今回使用するnasmではIntel記法を採用しています．

![Intel記法とAT&T記法](https://qiita-image-store.s3.amazonaws.com/0/77676/6234fd4e-698c-297b-a6c2-15387c83fae9.png)

# \:large_blue_diamond:アセンブラの足し算
```
    add <レジスタ>,<レジスタor規定値>
```
足し算には`add`命令を使います．
計算結果は第一引数のレジスタに代入されます．

# \:large_blue_diamond:アセンブラの引き算
```
    sub <レジスタ>,<レジスタor規定値>
```
引き算には`sub`命令を使います．
これも、計算結果は第一引数のレジスタに代入されます．


# \:large_blue_diamond:アセンブラの掛け算
```
    mul <レジスタ>
```
掛け算には`mul`命令を使います．
引数がひとつしかありません．もう一つの引数はAレジスタ(AL,AX,EAX)の値が使われ、結果はAレジスタ・Dレジスタに格納されます．これは、桁溢れを防ぐためです．結果の保存先は引数ののバイト長に依存します．

| 引数のサイズ | 結果の上半分のバイトの保存先 | 結果の下半分のバイトの保存先 |
|:------------|:------------|:----------------|
| 1バイト | AH | AL |
| 2バイト | DX | AX |
| 4バイト | EDX | EAX |


# \:large_blue_diamond:アセンブラの割り算
```
    div <レジスタ>
```
割り算には`div`命令を使います．
引数を一つしか取りません．引数として渡すのは除数で、被除数はAレジスタの値を使います．計算結果は商と剰余に別れてレジスタに保存されます．`mul`の時と同様に引数のバイト長に応じて結果の保存先が変わります．

| 引数のサイズ | 商の保存先 | 剰余の保存先 |
|:-----------|:----------|:------------|
| 1バイト    | AL | AH |
| 2バイト | AX | DX |
| 4バイト | EAX | EDX|

# \:large_blue_diamond:デモコード
上の演算の使い方を説明するコードです．

``` :atithmetic_operations.asm
section .bss

section .data

section .text

global main

main:
   enter 0,0
   nop

.add:
   xor eax, eax
   xor ebx, ebx
   mov eax, 2
   mov ebx, 7
   add eax, ebx

.sub:
   xor eax, eax
   xor ebx, ebx
   mov eax, 10
   mov ebx, 7
   sub eax, ebx

.mul:
   xor eax, eax
   xor ebx, ebx
   mov ax, 10
   mov bl, 2
   mul bl

.div:
   xor eax, eax
   xor ebx, ebx
   mov ax, 10
   mov bl, 3
   div bl

.final:
    mov eax, 0
    leave
    ret
```
このプログラムを
```
nasm -f elf64 -o arithmetic_operations.o arithmetic_oprations.asm
gcc -o arithmetic_operations arithmetic_operations.o
```
で、コンパイルしてださい．
```
gdb -tui arithmetic_operations
```
で、[gdb](http://qiita.com/MoriokaReimen/items/b316a68d76c1eafa18f8)を使えば、どのように処理されるか見えるはずです．

# 参考文献
* NASM development team site:   
http://www.nasm.us/
* GDB: The GNU Project Debugger site:   
https://www.gnu.org/software/gdb/
* Assembly Language Step-by-Step: Programming with Linux:   
http://www.amazon.co.jp/Assembly-Language-Step---Step-Programming/dp/0470497025/ref=sr_1_1?ie=UTF8&qid=1446704607&sr=8-1&keywords=assembly+language+step+by+step
 
↓↓\:bowtie:過去の投稿もよろしくね\:bowtie:↓↓

* Linuxでx86アセンブラ(Cとの連携編)
http://qiita.com/MoriokaReimen/items/590a4ddb3de15bfacb4b

* Linuxでx86アセンブラ(道具編)
http://qiita.com/MoriokaReimen/items/b316a68d76c1eafa18f8

* tmuxの使い方
http://qiita.com/MoriokaReimen/items/d7d5b158cb412dd65a60



↓↓\:bowtie:コメントをいただけたら励みになります\:bowtie:↓↓