GAS_演算子
代入演算子(assignment operator)
GAS (The GNU Assembler)を含め、アセンブリ言語では基本的な代入を行う場合にはmov命令を用います。
mov [代入元], [代入先]
- 代入によって代入元が空になったりすることはありません。
- レジスタを利用するときは、名前の先頭に%をつけます。
算術演算子(arithmetic operator)
四則演算
add [加算する値] [加算先]
sub [減算する値] [減算先]
mul [乗算する値]
div [除算する値]
- 乗算と除算はアキュムレータレジスタ(eaxやax)の値に対して演算を行います。
- 除算の場合、商はeaxに格納され、余りはedxに格納されます。
- 除算は処理に時間がかかるため、シフト演算することが一般的です。
下記は四則演算を実行して、結果をprintfで標準出力しています。
mulとdivではebxレジスタを一時的に利用してeaxに対する演算を行っています。
.file "arithmetic.s"
.data
MSG: .string "%d\n"
.text
.global main
main:
push %ebp
movl %esp, %ebp
movl $2, %eax # eax = 2
addl $2, %eax # eax = 2 + 2
subl $2, %eax # eax = 4 - 2
movl $3, %ebx # ebx = 3
mull %ebx # eax = 2 * 3
movl $0, %edx # 余り領域の初期化
divl %ebx # eax = 6 / 3
/* printfで出力する */
pushl %eax
pushl $MSG
call printf
leave
ret
インクリメントとデクリメント
値を1つ増やす、または1つ減らす演算です。
inc [加算先]
dec [減算先]
論理演算子(logical operator)
ビット演算を行う命令は以下の通りです。
or [演算値] [論理和の格納先]
and [演算値] [論理積の格納先]
xor [演算値] [排他的論理和の格納先]
not [演算値] [否定の格納先]
下記はビット演算を実行して、結果をprintfで標準出力しています。
.file "logical.s"
.data
MSG: .string "0x%08x\n"
.text
.global main
main:
push %ebp
movl %esp, %ebp
movl $0xFFFF0000, %eax
orl $0x0000FFFF, %eax # eax = 0xFFFFFFFF
andl $0x0000FFFF, %eax # eax = 0x0000FFFF
xorl $0xF0F00F0F, %eax # eax = 0xF0F0F0F0
notl %eax # eax = 0x0F0F0F0F
/* printfで出力する */
pushl %eax
pushl $MSG
call printf
leave
ret
シフト演算
シフト演算とは論理演算と同じようにビットを操作する命令です。
シフト演算では、左右のシフト方向、符号の有無で4種類を使い分けます。
符号なし整数のシフト(論理シフト)
論理シフトでは、足りなくなる桁には無条件に0が入ります。
シフト演算の結果はみ出す1桁はEFLAGS上のキャリーフラグ(CF)に格納されます。
shr [右シフトする桁数] [論理和の格納先]
shl [左シフトする桁数] [論理積の格納先]
- shr = shift Logical right
- shl = shift Logical left
符号付き整数のシフト
符号付き整数のシフトは、符号(上位1bit)を壊さないようにシフトさせる演算です。
sar [右シフトする桁数] [論理和の格納先]
sal [左シフトする桁数] [論理積の格納先]
- sar = shift Arithmetic right
- sal = shift Arithmetic left
シフト演算サンプル
符号有無によるシフト演算の違いは下記の通りです。
shr命令は符号を無視して桁を0で埋めます。
sar命令は符号を壊さないように桁を1で埋めます。
.file "shift_calc.s"
.data
MSG: .string "%d\n"
.text
.global main
main:
push %ebp
movl %esp, %ebp
movl $0xFFFFFFFF, %eax # eax = -1
shrl $16, %eax # eax = 65535
shrl $8, %eax # eax = 255
movl $0xFFFF0000, %eax # eax = -65535
sarl $8, %eax # eax = -256
sarl $4, %eax # eax = -16
/* printfで出力する */
pushl %eax
pushl $MSG
call printf
leave
ret
関連ページ
- GAS_基本文法
- GAS_基本書式
- GAS_演算子
- GAS_制御構造
- GAS_関数
- GAS_システムコール
- GAS_標準ライブラリ関数
- GAS_Intel記法の利用
- GAS_インラインアセンブラ
- アセンブリ言語