Hello, Rust! – インラインアセンブリとセクション

前回の記事では、Rustを使用したHello, Worldについて紹介しました。今回も同じ題材を使用して、Rustで低レイヤプログラミングを行うための細かなテクニックについて紹介します。

インラインアセンブリ

Rustのようなシステムプログラミング言語を使用していても、時には、どうしてもアセンブリを書きたいときがあります。
  • 特殊な命令を使用したい
  • 特定のレジスタにアクセスしたい
  • コンパイラの出すコードが気に入らない
前回はスタートアップコードをARMアセンブリで書きましたが、これはレジスタr13にスタックを明示的に格納する必要があったからです。しかし、コードの一部をアセンブリで書きたいと思った時に、関数インタフェースを考えて別ファイルに実装し、アセンブラでコンパイルしなくてはならないのは面倒ですよね。

実は、そんな時のために、Rustではインラインアセンブリが書けるようになっています。

assembly templateにアセンブリを文字列リテラルで書きます。output/input operandsは、コード中の変数とのインタフェースになります。clobbersには破壊されるレジスタを指定します。optionsには必要であれば”volatile”や”intel”のようなオプションを渡すことが出来ます。

セクション名の指定

プログラムの実行時に特定の関数を特定のアドレスに配置したい、といった場合、リンカスクリプトを書く必要があります。例えば、前回の例では、startup.oというオブジェクトに含まれるコードセクションを他オブジェクトよりも先に配置するようなスクリプトを書きました。
一方で、よりきめ細やかに関数単位で配置を指定したい、という要求もあります。よく用いられる手法は、ELFのセクション名をコードに埋め込んでおき、リンカスクリプトでそれをキーにして配置制御を行う、という手法です。
Rustでは、link_sectionアトリビュートを使用して、セクション名とシンボルを結びつける事ができます。

使ってみる

こんな感じです。

ビルドもちょっとだけ楽ちんになりました。

rustc –target=arm-unknown-linux-gnueabi -C target-cpu=cortex-a9 -C no-stack-check -o hello.o hello.rs

arm-none-eabi-ld -T linker.ld -o hello.elf hello.o

続く?

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です