26
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

Linuxでx86アセンブラ(四則演算編)

:large_blue_diamond:この記事について

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

使用するソフトウェア

この連載ではLinux環境でnasmを使用することを想定しています.

:large_blue_diamond:ニーモニックとオペランド

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

オペランドとニーモニック

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

Intel記法とAT&T記法

: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を使えば、どのように処理されるか見えるはずです.

参考文献

↓↓:bowtie:過去の投稿もよろしくね:bowtie:↓↓

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
26
Help us understand the problem. What are the problem?