WebAssembly の短期集中コース

この記事は WebAssembly と何が速くしたのかのシリーズの 3 部です。もしまだ前の記事を読んでいない場合、最初から読むことをお勧めします。どのように WebAssembly が動いているかを理解するために、アセンブリが何でありどのようにアセンブリを生成するのかを理解することが役に立ちます。

JIT の記事では、機械とのやりとりがエイリアンとのコミュニケーションのようなものだと話しました。

A person holding a sign with source code on it, and an alien responding in binary

エイリアンの脳がどのように働いているのか、機械の脳はどのように解析してそこに入ってくるコミュニケーションを理解しているのかを見てみたいと思います。

この脳の一部は、思考に専念しています。つまり、加減算や論理演算などです。短期記憶を提供する脳の部分と、長期記憶を提供するもう一つの部分もあります。

これらの異なる部分には名前があります。

  • 思考を行う部分は算術論理ユニット (ALU) です。
  • 短期記憶はレジスタによって提供されます。
  • 長期記憶はランダムアクセスメモリ (もしくはRAM) です。

A diagram showing the CPU, including ALU and Registers, and RAM

マシン語の文章は命令と呼びます。

これらの命令の 1 つが脳に入ったらどうなりますか?それは異なることを意味する異なる部分に分割されます。

この命令が分割される方法はこの脳の配線に固有のものです。

例えばこのように配線された脳は、常に最初の 6 ビットを取り、それを ALU にパイプすることができます。 ALU は 1 と 0 の位置に基づいて、2 つのものを一緒に追加する必要があることを理解します。

この 塊は ALU にどのような操作を実行するかを指示するため、「オペコード」またはオペレーションコードと呼ばれます。

6-bits being taken from a 16-bit instruction and being piped into the ALU

次に、この脳は次の 2 つのチャンクをそれぞれ 3 ビットずつ取って、どの 2 つの数字を追加するかを決定します。 これらはレジスタのアドレスになります。

Two 3-bit chunks being decoded to determine source registers

ここで機械語の上に注釈があることに注意してください。これは人間が何が起こっているのかを理解しやすくします。これがアセンブリです。シンボリックマシンコードとも呼ばれており、人間が機械語を理解する方法です。

ここには、この機械のためのアセンブリと機械語の間にかなり直接的な関係があることがわかります。このため、さまざまな種類の機械のアーキテクチャー向けにに異なる種類のアセンブリがあります。機械の内部で別のアーキテクチャを使用している場合は、独自の方言のアセンブリが必要になる可能性があります。

だから私たちは翻訳の目標を一つだけ持っているわけではありません。これは、機械語と呼ばれる単なる言語ではありません。これは、さまざまな種類の機械語です。私たちが人としてさまざまな言語を話すように、機械は異なる言語を話します。

人からエイリアンへの翻訳では英語、ロシア語、または北京語からエイリアン語Aまたはエイリアン語Bに移行している可能性があります。プログラミング上、これはC、C ++、Rustからx86またはARMへの変換に似ています。

これらの高レベルのプログラミング言語のいずれかをこれらのアセンブリ言語のいずれかに翻訳したいと考えています (異なるアーキテクチャに対応しています)。これを行うための 1 つの方法は、各言語から各アセンブリに変換することができるさまざまな翻訳者をたくさん作成することです。

Diagram showing programming languages C, C++, and Rust on the left and assembly languages x86 and ARM on the right, with arrows between every combination

それはかなり非効率的になるでしょう。これを解決するため、ほとんどのコンパイラは少なくとも 1 つのレイヤを中間に配置します。コンパイラはこの高水準のプログラミング言語をとり、これを高レベルではないものに変換しますが、機械語のレベルでは動作しません。 それは中間表現 (IR) と呼ばれています。

Diagram showing an intermediate representation between high level languages and assembly languages, with arrows going from high level programming languages to intermediate representation, and then from intermediate representation to assembly language

これはコンパイラがこれらの上位レベルの言語のいずれかを取り、それを 1 つの IR 言語に翻訳できることを意味します。そこから、コンパイラの別の部分がその IR を取得し、ターゲットアーキテクチャに固有のものにコンパイルすることができます。

コンパイラのフロントエンドは、上位レベルのプログラミング言語を IR に変換します。コンパイラのバックエンドは、IR からターゲットアーキテクチャのアセンブリコードに移行します。

Same diagram as above, with labels for front-end and back-end

Conclusion

これはアセンブリの仕組みと、コンパイラがどのように高水準のプログラミング言語をアセンブリに変換するかです。次の記事では、WebAssembly がこれにどのように適合するかを見ていきます。

Lin Clark に関して

Lin は Mozilla Developer Relations チームのエンジニアです。 彼女は JavaScript、WebAssembly、Rust、Servo を使っています。また、コードの漫画を描きます。

Lin Clark によるその他の記事はこちら…

コメントを投稿する