ARMの命令セット(v7)について調べていたので備忘録のためメモを残しておきます。
■ARMv7のマニュアル
とりあえず命令セットのところを読んでみる。
参考用に簡単な加算と条件分岐を含むコードを書いてみる。
■サンプルコード hoge.c
int add(void) { int a = 0; a += 0x10; if ( a == 0x10) { return a; } return 0; }
$ arm-linux-gnueabi-gcc -g -c hoge.c
$ arm-linux-gnueabi-objdump -S hoge.o
■サンプルアセンブラコード
00000000 <add>: int add(void) { 0: e52db004 push {fp} ; (str fp, [sp, #-4]!) 4: e28db000 add fp, sp, #0 8: e24dd00c sub sp, sp, #12 int a = 0; c: e3a03000 mov r3, #0 10: e50b3008 str r3, [fp, #-8] a += 0x10; 14: e51b3008 ldr r3, [fp, #-8] 18: e2833010 add r3, r3, #16 1c: e50b3008 str r3, [fp, #-8] if ( a == 0x10) { 20: e51b3008 ldr r3, [fp, #-8] 24: e3530010 cmp r3, #16 28: 1a000001 bne 34 <add+0x34> return a; 2c: e51b3008 ldr r3, [fp, #-8] 30: ea000000 b 38 <add+0x38> } return 0; 34: e3a03000 mov r3, #0 } 38: e1a00003 mov r0, r3 3c: e24bd000 sub sp, fp, #0 40: e49db004 pop {fp} ; (ldr fp, [sp], #4) 44: e12fff1e bx lr
条件指定について
ARMの命令のうち、最上位の4bitは条件指定のビット(cond)として割り当てられているそうです。
逆アセンブラを見るとこのcondビットはほぼほぼ1111(0xE..)になっていることが多い。
ここまでは過去の経験として知っていたのですが、このcondビットの意味がいまいちよく分かっていませんでした。※そういえばpine64のダンプとか読んだときも少し調べていました。
結論ですが、ARMでは(ほとんどの)命令に対して実行するかしないかの条件をつけることができるそうです。これだけだとピンとこないのですが、条件と言うのは要するにフラグレジスタの各種フラグビット(ゼロフラグとかキャリーフラグ...etc)に応じて実行するかしないかを命令に対して指定できるという意味になります。
実際に、上記のhoge.oの逆アセンブルですとbneだとcondは1になっています。
条件指定実行ができるということは
addとかmov命令をフラグレジスタの値を元に実行するかしないか切り替えれるというような意味だと思います。*1
というわけで実際にどの命令で条件指定が可能なのか、適当に試してみたいと思います。
が、今日眠いので続きは明日にします。
[2018/06/06 追記]
条件実行について更に調べてみた続きです。