とあるエンジニアの備忘log
2012年4月6日金曜日
拡張インラインアセンブラの勉強 1
拡張インラインアセンブラ、けっこう難しくてなかなか覚えられません。。 [GCC Inline Assembler](http://caspar.hazymoon.jp/OpenBSD/annex/gcc_inline_asm.html) というサイトを見ながら、もう一回勉強してみた。 基本的に asm( アセンブリテンプレート : 出力オペランド : 入力オペランド : 破壊レジスタ); というフォーマットでいいのですが、「出力オペランド」と「入力オペランド」はわかるとして、 「破壊レジスタ」というのがいまいちピンときません。 そこで、「破壊レジスタ」を指定するのとしないのとで、どのような違いが出るのか、 ARM gcc の逆アセを見ながら勉強してみた。 まずは、普通に(拡張でない)インラインアセンブラを書いた場合 int hoge() { register int a = 10, b = 20; asm("mov r4, #100"); return a + b; } をコンパイルすると
: push {r4, r5, fp} add fp, sp, #8 mov r5, #10 mov r4, #20 mov r4, #100 ; 0x64 add r3, r5, r4 mov r0, r3 sub sp, fp, #8 pop {r4, r5, fp} bx lr となった。 コンパイラは前後関係を考慮することなく、単に `mov r4, #100` を挿入するだけなので、 `30` ではなく、 `110` を返すコードが生成された。 (変数 `b` が `r4` に取られているためだが、これは事前に予測不能である。) そこで拡張インラインアセンブラを使って、 `r4` が破壊されることを指定する。 int hoge() { register int a = 10, b = 20; asm("mov r4, #100" : : : "r4"); return a + b; } は
: push {r4, r5, r6, fp} add fp, sp, #12 mov r6, #10 mov r5, #20 mov r4, #100 ; 0x64 add r3, r6, r5 mov r0, r3 sub sp, fp, #12 pop {r4, r5, r6, fp} bx lr なるほど、 `r4` を避けて、 変数 `a`, `b` を `r6`, `r5` に割り当てています。 しかもちゃんと `r4` をスタックに退避してくれています。 ではコンパイラを困らせてやれと思って、 int hoge() { register int a = 10, b = 20; asm("mov r4, #100" : : : "r4", "r5", "r6", "r7", "r8", "r9", "r10"); return a + b; } とすると、
: push {r4, r5, r6, r7, r8, r9, sl, fp} add fp, sp, #28 sub sp, sp, #8 mov r1, #10 str r1, [fp, #-32] ; 0xffffffe0 mov r2, #20 str r2, [fp, #-36] ; 0xffffffdc mov r4, #100 ; 0x64 ldr r1, [fp, #-32] ; 0xffffffe0 ldr r2, [fp, #-36] ; 0xffffffdc add r3, r1, r2 mov r0, r3 sub sp, fp, #28 pop {r4, r5, r6, r7, r8, r9, sl, fp} bx lr となった。 レジスタ変数をとれなくなって、変数 `a`, `b` はスタックに確保している。 ただし、破壊レジスタに `r11` を指定すると error: fp cannot be used in asm here というエラーが出る。 一応、以下のようにほとんど破壊レジスタリストに指定しても、つじつまの合うように動くようです。 int hoge() { register int a = 10, b = 20; asm("mov r13, #0x81000000" : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "r13", "r14"); return piyo(a, b); } をコンパイルすると、
: push {r4, r5, r6, r7, r8, r9, sl, fp, lr} add fp, sp, #32 sub sp, sp, #12 mov r3, #10 str r3, [fp, #-40] ; 0xffffffd8 mov r3, #20 str r3, [fp, #-44] ; 0xffffffd4 mov sp, #-2130706432 ; 0x81000000 ldr r0, [fp, #-40] ; 0xffffffd8 ldr r1, [fp, #-44] ; 0xffffffd4 bl
mov r3, r0 mov r0, r3 sub sp, fp, #32 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc}
0 件のコメント:
コメントを投稿
次の投稿
前の投稿
ホーム
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿