Article

2015年6月23日

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

インラインアセンブリ

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

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

<span class="macro" style="box-sizing: border-box; color: #3e999f;">asm</span><span class="macro" style="box-sizing: border-box; color: #3e999f;">!</span>(<span class="ident" style="box-sizing: border-box;">assembly</span> <span class="ident" style="box-sizing: border-box;">template</span>
   : <span class="ident" style="box-sizing: border-box;">output</span> <span class="ident" style="box-sizing: border-box;">operands</span>
   : <span class="ident" style="box-sizing: border-box;">input</span> <span class="ident" style="box-sizing: border-box;">operands</span>
   : <span class="ident" style="box-sizing: border-box;">clobbers</span>
   : <span class="ident" style="box-sizing: border-box;">options</span>
   );

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

セクション名の指定

プログラムの実行時に特定の関数を特定のアドレスに配置したい、といった場合、リンカスクリプトを書く必要があります。例えば、前回の例では、startup.oというオブジェクトに含まれるコードセクションを他オブジェクトよりも先に配置するようなスクリプトを書きました。
一方で、よりきめ細やかに関数単位で配置を指定したい、という要求もあります。よく用いられる手法は、ELFのセクション名をコードに埋め込んでおき、リンカスクリプトでそれをキーにして配置制御を行う、という手法です。
Rustでは、link_sectionアトリビュートを使用して、セクション名とシンボルを結びつける事ができます。
<span class="attribute" style="box-sizing: border-box; color: #c82829;">#[link_section="foo"]</span>
<span class="kw" style="box-sizing: border-box; color: #8959a8;">fn <span class="ident" style="box-sizing: border-box;">foo</span>() {
  <span class="comment" style="box-sizing: border-box; color: #8e908c;"><...snip...></span>
}

使ってみる

こんな感じです。

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

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

続く?

Tags

About Author

iitaku

Leave a Comment

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

Recent Comments

Social Media