ARM アセンブラ C 関数コール
main() から関数 kakeruni() をコールする C ソースをコンパイルしてアセンブラを観察してみました。
まず、C ソースは下記の通りです。
このコンパイル結果のアセンブラです。
main() および kakeruni() ともに数字で分類したような処理内容になっているようです。
① FP 等の PUSH、引数(R0,R1,...)の保存(ストア)
② オペランド値のレジスタ書込み(ロード)
③ 演算処理、結果のレジスタ書込み(R0)
④ SP 設定とPOP、ブランチ(リターン)
main() は kakeruni() をコールするので、LR (Link Register, R14) と FP (Frame Pointer, R11) をPUSHで保存しますが、kakeruni() はコールする関数も無いので FP しか PUSH しません。
これに関係しているのか、POP してブランチで戻る際の処理が、main() では、
pop {fp, pc}
ですが、kakeruni() では下記のようになっています。
ldmfd sp!, {fp}
bx lr
main() のように pop で PC (Program Counter, R15) を PUSH で保存しておいた LR に上書きしてする方式はすっきりしているように思えます。kakeruni() のように ldmfd (popと等価) と bx に分けるのは何かメリットがあるのでしょうかね…
最後に念のためコンパイラツールのバージョン情報です。
$ arm-xilinx-linux-gnueabi-objdump --version
GNU objdump (Sourcery CodeBench Lite 2013.05-40) 2.23.52.20130219
まず、C ソースは下記の通りです。
このコンパイル結果のアセンブラです。
main() および kakeruni() ともに数字で分類したような処理内容になっているようです。
① FP 等の PUSH、引数(R0,R1,...)の保存(ストア)
② オペランド値のレジスタ書込み(ロード)
③ 演算処理、結果のレジスタ書込み(R0)
④ SP 設定とPOP、ブランチ(リターン)
main() は kakeruni() をコールするので、LR (Link Register, R14) と FP (Frame Pointer, R11) をPUSHで保存しますが、kakeruni() はコールする関数も無いので FP しか PUSH しません。
これに関係しているのか、POP してブランチで戻る際の処理が、main() では、
pop {fp, pc}
ですが、kakeruni() では下記のようになっています。
ldmfd sp!, {fp}
bx lr
main() のように pop で PC (Program Counter, R15) を PUSH で保存しておいた LR に上書きしてする方式はすっきりしているように思えます。kakeruni() のように ldmfd (popと等価) と bx に分けるのは何かメリットがあるのでしょうかね…
最後に念のためコンパイラツールのバージョン情報です。
$ arm-xilinx-linux-gnueabi-objdump --version
GNU objdump (Sourcery CodeBench Lite 2013.05-40) 2.23.52.20130219