アセンブリ言語
前述のインテルの MOV のようにデータの転送の多くを同一の命令あるいはニーモニックとする場合もあれば、データのコピー/移動の方向などによって別々の命令あるいはニーモニックとする場合もある(「メモリからレジスタへの移動」を L、「レジスタからメモリへの移動」を ST、「レジスタからレジスタへの移動」を LR、「即値をメモリへ移動」を MVI など)。(この段落では命令セットの設計の話とアセンブリ言語の話を一緒にしている)
インテルのオペコード 10110000(B0)は8ビットの値を AL レジスタにコピーするが、10110001(B1)はCLレジスタにコピーし、10110010(B2)は DL レジスタにコピーする。これらをアセンブリ言語で表現すると次のようになる。
MOVの構文には次の例のようにさらに複雑なものもある。
MOVというニーモニックを使った文は、その内容によってアセンブラが88-8E、A0-A3、B0-B8、C6、C7のいずれかのオペコードに変換するので、プログラマはオペコードを知る必要がないし、オペコードを覚える必要もない。
アセンブラの開発者によって用語の使い方に大きな差異があり、文の分類などが異なる。例えば、マシンのニーモニックや拡張ニーモニック以外は全て擬似命令と呼ぶ場合もある。典型的なアセンブリ言語は、プログラムの操作の定義に使われる命令文をニーモニック、データセクション、アセンブリディレクティブの3種類に分類する。
vDSOを用い、プロセスからはシェアードオブジェクトを読み込んだように見せる実装が多い。 見せるコードの範囲を正確に把握する必要があるため、コードのエントリだけでなく終了部にもラベルを与える。アセンブリ言語では容易だが、高級言語では一般に不要な機能なのでサポートされていない。 元来はユーザモード用のスタック上にカーネルからコードをコピーして実行していた。欠点として、スタックはユーザモードでの書き込みが禁止できず、スタック上でのコード実行がセキュリティホールとしてしばしば利用されたことから、実装方法の変更が進められている。
オブジェクトファイルに依存した機能 コンパイラが通常は使用しないセクション等にシンボルを定義することができる。例として、Linuxカーネルではモジュールへ公開するシンボルをマクロEXPORT_SYMBOL(ないしはその派生)へ与える。このマクロは、インラインアセンブリを用いてオブジェクトファイルのセクション.export_symbolへシンボルの情報を追加し、モジュールローダがシンボル解決にて使用できるようにする。マクロの内容はCPUアーキテクチャには依存せず、その定義もCPUアーキテクチャに依存しないヘッダファイル(include/linux/export.h)にあるが、C言語を含め高級言語のみでの実装が難しく、アセンブリが適している。
なお一方で、最近のコンピュータの命令セットはその多くはどれも似ている。したがって、どれか1つのアセンブリ言語を学ぶだけで、基本概念、どんなときにアセンブリ言語を使用するのが適しているか、高水準言語から効率的な実行コードを生成する方法をある程度は学習できる。
■カテゴリ / ■テンプレート
アセンブリ言語(アセンブリげんご、英: assembly language、アセンブリ)はビット列命令に対応した文字列命令を利用する低水準プログラミング言語の総称である。
アセンブラ(英: Assembler)またはアセンブラ言語(英: Assembler Language)とも呼ばれる。
アセンブラは様々な観点から分類できる。パス回数(アセンブル時のソースファイル走査回数)の観点ではワンパスアセンブラとマルチパスアセンブラに分類できる。
シンボリックアセンブラでは、任意の名前(ラベルまたはシンボル)とメモリ位置を対応付けることができる。通常、定数や変数に名前をつけることができ、命令文ではそれらの位置を名前で参照できる。実行コードではサブルーチンのエントリポイントと名前を関連付け、サブルーチンを名前で呼び出すことができる。サブルーチン内では、分岐命令の分岐先をラベルで示すことができる。一部のアセンブラは「ローカルシンボル」をサポートしており、通常のシンボルとは語彙的に区別する(例えば、"10$"を分岐先に使用する、など)。
一部のアセンブラは柔軟なシンボル管理を提供しており、複数の名前空間を管理したり、データ構造内のオフセットを自動的に計算したり、リテラル値やアセンブラが実施した単純な計算結果を参照するラベルを割り当てたりすることができる。ラベルは定数や変数をリロケータブルなアドレスで初期化するのにも使える。