create every day - 福野泰介の一日一創

プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2

2017/11/09 23:55:00
#asm #wasm #js 

前回「ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1」では、マシン語の命令表からひとつずつ選んで数を書いてみました。 プログラムをこのようにマシン語にする作業のことをアセンブル(英語で組み立てを意味する)と言います。

数が多くなってくると、こうして手で変換するのは大変なので、プログラムを作って自動化しましょう。 今使っている環境の範囲だけで動く簡易的なアセンブラ「WebAssembly poor assembler」をJavaScriptで作りました。


WebAssembly poor assembler

こちら、前回はマシン語だった param+1 を計算するプログラムのアセンブリ言語プログラムです。

get_local $0 i32.const 1 i32.add end

「ASSEMBLE」ボタンを押すと、下に数字の並びに変換され、RUNで動かせます。

20 0 41 1 6a b

試しに、i32.add を i32.mul に書き換えて、ASSEMBLE、RUNしてみましょう。
i32.const 1 を i32.const 5 に書き換えて、ASSEMBLE、RUNしてみましょう。
param に、10と入力しなおして、RUNしてみましょう。

ちょっとだけ複雑な計算をさせてみます。

get_local $0 i32.const 5 i32.mul i32.const 1 i32.add end

i32.const 1 と i32.add を書き加えて、n*5+1 を計算するプログラムにしました。
ASSEMBLE、RUNしたり、paramを書き換えてみましょう。

このようにアセンブルを自動化するプログラムのことを、アセンブラといいます。
(手でアセンブルすることをハンドアセンブルといい、アセンブラがない時代の必須テクニックでした)

次はコンパイラを作ってみます。お楽しみに!

WebAssemblyマシン語入門
- ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1
- プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2

ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1

2017/11/07 23:55:00
#asm #wasm 

コンピューターの気持ちに近づけるマシン語。
IchigoJamだけで始めるARMマシン語入門に続き、
ブラウザだけで始めるWebAssemblyマシン語入門その1です。

コンピューターは高速に計算する機械(=マシン)です。

メモリ(=記憶装置)に2つの数があったら足し算する電子回路があるとします。
1と1をメモリに書いたら瞬時に2が得られます。
(参考「なぜコンピューターは計算が速いのか? 電気回路で計算ができる謎を解く」)

足し算だけだと使いみちが限られるので、引き算・掛け算や、計算順序を変える機能などを追加します。
機能を区別する方法は何でもいいのですが、計算が得意なコンピューターのために、それぞれの機能に数を割り当ててあげると効率的です。
やってほしい計算を表す数をずらずらと並べたもの、これがマシン語プログラムとなります。

IchigoJamで使っているのはARMという会社が考えたコンピューターなので、ARMマシン語。
今回使うWebAssemblyマシン語は、ブラウザで動くことにした仮想的なコンピューターです。
仮想的とは、マシン(ハードウェア)をソフト(=プログラム)で表現したものを言います。

とりあえず、動かしてみましょう。
WebAssembly testenv」を開き、「RUN」を押すと、2とでます。


WebAssembly testenv」で、1+1=2 をマシン語プログラムでつくり、動かした様子

「param」に1と書いてあるものを、10に変えて、もう一度「RUN」を押してみましょう。
きっと、今度は11と出ます。
(もし動かないならば、きっとお使いのブラウザがWebAssemblyに対応していません!Chrome/FireFox/Safariの最新版をダウンロードしましょう)

20 0 41 1 6a 0b

実はこれがWebAssemblyのマシン語です。(0〜9とa〜fの15種類の文字を使った16進法表記)

右の表を照らし合わせてみると・・・
20 0 ・・・ get_local $0 (渡された数をメモリに書くよ)
41 1 ・・・ i32.const 1 (1をメモリに書くよ)
6a ・・・ i32.add (メモリに書かれた2つの数を足してメモリに書くよ)
0b ・・・ end (プログラムを終わって、メモリに書かれたものを返すよ)

と解読できます。

10-1を計算させるには、i32.add (6a) の代わりに i32.sub (6b) を使います。

20 0 41 1 6b 0b

計算できました!

コードの上に書いてある、WebAssmeblyマシン語であることを表すIDなどと組み合わせて、.wasmファイルを作成すれば、ブラウザ上で高速に動くプログラムができるわけです!

右の表にあるものはもちろん一部です。
興味があればWebAssemblyの仕様書を覗いてみましょう。

ひとつひとつ表から照らし合わせてプログラムを書くのは大変なので、普通はこの作業をプログラムで自動化します。
アセンブラとか、コンパイラなどと呼ばれるソフトで、その数だけプログラミング言語があるわけですね!

マシン語が分かれば自分だけのプログラミング言語を作ることもできちゃいます!
日本生まれで世界に広がるプログラミング言語 Ruby に続こう!

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / high-res profile image