0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

WebAssembly + C/C++ でもインラインアセンブラ使いたい

Last updated at Posted at 2020-10-06

はじめに

Cでx86とかarmターゲットだとインラインアセンブラを書けるけれども、WebAssemblyターゲットでもインラインアセンブラ書きたいですよね...? (そんな人はこれまでにいなかったと願っておくのです)

各サンプルに、WebAssemblyStudio での実行用プロジェクトへのリンクを追加しています。ソースファイルの編集はPCブラウザでなければ正常にできませんが、スマホでも実行ができると思います。必要に応じて活用してください。

対象読者

目標

  • C言語ソースファイル中のインラインアセンブラとして、WebAssembly テキストフォーマットを使いこなせるようになる

注意書き

WebAssemblyターゲットのインラインアセンブラに関する情報は、皆無に等しい状態です。そのため、筆者の手元の環境でコンパイル/実行できるサンプルを掲載しています。

検証環境

  • emscripten 2.0.3
  • clang 12.0.0

レベル1: 加減乗除

シンプルに 12 + 34 を計算し、その値を main 関数の戻り値としています。

オンラインサンプル: WebAssembly Studio#?zaqqdfn25vo

int main() {
  __asm (
    "i32.const 12\n"
    "i32.const 34\n"
    "i32.add     \n"
    "br 0"
  );
}

スタックに 12, 34 を追加し、スタック上の2数を足してスタックに戻し、スタック上の数値を関数の戻り値にするという、WebAssemblyスタックマシンでの一連の命令です。

レベル2: 変数を読み書きする

変数 val にインラインアセンブラで書き込みを行うものです。

オンラインサンプル: WebAssembly Studio#?81by60h3kr4

int main() {
  int val;

  __asm (
    "i32.const 12\n"
    "i32.const 34\n"
    "i32.add     \n"
    "local.set %0"
    : "=r"(val)
  );

  return 0;
}

変数 val はスタック上に存在しますが、"=r"(val) と指定することで、スタック変数をローカル変数にコピーする処理をコンパイラが追加してくれます。

レベル3: 関数呼び出し

C言語標準関数の puts をインラインアセンブラで呼んでみます。

オンラインサンプル: WebAssembly Studio#?imnemdya3kg

int main(void) {
  const char Hello[] = "Hello World\n";
  
  __asm (
    "local.get %0\n"
    "call %1\n"
    "drop"
    : : "r"(Hello), "i"(puts)
  );
}

call 命令が、スタック上の値を引数の数だけ渡して関数を呼ぶ命令です。

サンプルでの %1 の代わりに関数名を指定することもできます。しかし、C++に持っていった時にマングリング名を指定するか extern "C" をつけたりするよりは、関数を即値として渡してしまった方が楽だったりします。(コンパイル結果も間接呼び出しではなく直接呼び出しになる)

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?