darakeLog

GNU as(AT&Tアセンブリ)のtest命令の意味や使い方についてまとめる

2020-04-07 14:29:35 アセンブリ

GNU as(AT&Tアセンブリ)の勉強をしているとtest命令というのが出てきたので、これを機に調べたことをまとめていく。

testとは何か?

testとは、2つのオペランド(引数)を論理和(AND)で計算して、結果が0であればZEROフラグを0にし、結果が1であればZEROフラグに1を立てる。

また、この論理和の計算結果は計算に使ったレジスタには影響を与えない。つまり、testcmpの論理和に特化した命令だと言える。

testの具体的な使い方は下記のコードのようになる。

    mov $0x03, %rax
    mov $0x01, %rcx
    test %rcx, %rax
    je test_ok

上記のコードではraxレジスタに3を代入しrcxレジスタに1を代入している。そして、三行目のtestで論理和を行なっているが、この論理和の計算結果は0にはならない。

よって4行目のje test_okは行われない、という処理になっている。

最初はtestの挙動を頭の中で整理するのは大変だが、慣れの問題だと思う。

testの具体的な使い方

では、実践的にはtestはどのように使われるかと言うと、「これまで計算した結果が0かどうかで処理を変えたい」という時に役立つ。

例えば、下記のように最終的な計算結果をraxに収める、という風に処理すると決める。

; たくさんの計算
mov %rcx, %rax ; 計算結果をraxへ
test %rax, %rax
je test_ng
jne test_ok

特徴的なのは3行目のtest %rax, %raxの部分。raxで論理和をすることで、raxが0だったらZEROフラグが立ち、0以外だとZEROフラグが立たない、という風にしている。

参考記事

TEST (x86 instruction) - Wikipedia

c - GDB / GNU assembly: test %esi,%esi returns not equal? - Stack Overflow