
コンピュータプログラミングにおいて、マシンコードは、コンピュータの中央処理装置(CPU)を制御するために使用される機械語命令で構成されるコンピュータコードです。従来のバイナリコンピュータの場合、マシンコードは「コンピュータによって実際に読み取られ、解釈されるコンピュータプログラムのバイナリ表現です。マシンコードのプログラムは、一連のマシン命令 (データが散在している場合もあります) で構成されます。」[1]
各マシン コード命令により、CPU は非常に特定のタスクを実行します。タスクの例には次のものがあります。
一般に、各アーキテクチャ ファミリ (例: x86、ARM ) には独自の命令セット アーキテクチャ(ISA) があり、したがって独自のマシン コード言語があります。ただし、PDP-11命令セットのオプション サポートを含むVAXアーキテクチャ、 IA-32命令セットのオプション サポートを含むIA-64アーキテクチャ、PowerPCと x86 の両方の命令セットをネイティブに処理できるPowerPC 615マイクロプロセッサなどの例外もあります。
マシンコードは厳密に数値的な言語であり、プログラマ向けの CPU への最低レベルのインターフェイスです。アセンブリ言語は 、数値マシンコードと人間が読めるニーモニックとの間の直接的なマップを提供します。アセンブリでは、数値オペコードとオペランドはニーモニックとラベルに置き換えられます。たとえば、x86アーキテクチャでは 0x90 オペコードを使用できます。これは、アセンブリソースコードではNOPとして表されます。マシンコードでプログラムを直接記述することは可能ですが、個々のビットを管理して数値アドレスを計算するのは面倒で、エラーが発生しやすくなります。したがって、プログラムがマシンコードで直接記述されることはほとんどありません。ただし、アセンブリソースコードが利用できない場合は、既存のマシンコードプログラムを編集できます。
今日のプログラムの大部分は高級言語で書かれています。高級プログラムはコンパイラによって機械語に変換されます。
命令セット
すべてのプロセッサまたはプロセッサ ファミリには独自の命令セットがあります。命令は、マシン コマンドに対応するビット、数字、または文字のパターンです。したがって、命令セットは (ほとんど) 同じアーキテクチャを使用するプロセッサのクラスに固有です。後継または派生プロセッサの設計には、多くの場合、先行プロセッサの命令が含まれており、新しい追加命令が追加されることがあります。場合によっては、後継の設計で一部の命令コードの意味が廃止されたり変更されたりすることがあり (通常は新しい目的に必要なため)、コードの互換性に多少影響します。互換性のあるプロセッサでも、一部の命令の動作がわずかに異なる場合がありますが、これが問題になることはほとんどありません。システムは、メモリ配置、オペレーティング システム、周辺機器など、その他の詳細でも異なる場合があります。プログラムは通常このような要素に依存しているため、同じタイプのプロセッサが使用されている場合でも、異なるシステムでは通常、同じマシン コードが実行されません。
プロセッサの命令セットには、固定長命令と可変長命令があります。パターンの構成方法は、特定のアーキテクチャと命令の種類によって異なります。ほとんどの命令には、基本命令タイプ(算術、論理、ジャンプなど)、操作(加算や比較など)を指定する1つ以上のオペコードフィールドと、オペランドのタイプ、アドレッシングモード、アドレッシングオフセットまたはインデックス、またはオペランド値自体(命令に含まれるこのような定数オペランドは即値と呼ばれます)を指定するその他のフィールドがあります。[2]
すべてのマシンや個々の命令に明示的なオペランドがあるわけではありません。アキュムレータが 1 つしかないマシンでは、アキュムレータは暗黙的にほとんどの算術命令の左オペランドと結果の両方になります。x86 アーキテクチャなどの他のアーキテクチャには、一般的な命令のアキュムレータ バージョンがあり、アキュムレータは長い命令によって汎用レジスタの 1 つと見なされます。スタック マシンでは、そのオペランドのほとんどまたはすべてが暗黙的なスタック上に存在します。特殊用途の命令にも明示的なオペランドがないことがよくあります。たとえば、x86 アーキテクチャの CPUID は、4 つの暗黙的な宛先レジスタに値を書き込みます。明示的なオペランドと暗黙的なオペランドのこの区別は、コード ジェネレータ、特にレジスタ割り当てと有効範囲の追跡部分で重要です。優れたコード オプティマイザは暗黙的なオペランドと明示的なオペランドを追跡できるため、より頻繁な定数伝播、レジスタの定数畳み込み(定数式の結果が割り当てられたレジスタをその定数に置き換えることで解放する)、およびその他のコード拡張機能が可能になります。
プログラム
コンピュータプログラムとは、中央処理装置(CPU)で実行できる命令のリストです。プログラムの実行は、それを実行する CPU が問題を解決して結果を達成するために行われます。単純なプロセッサは命令を次々に実行できますが、スーパースカラープロセッサは、特定の状況 (パイプラインがいっぱいの場合) で 2 つ以上の命令を同時に実行できます。たとえば、1993 年のオリジナルのIntel Pentium は、パイプラインがいっぱいの場合、クロック サイクルごとに最大 2 つの命令しか実行できません。
プログラム フローは、実行を次の数値順のアドレス以外のアドレス (つまり命令) に転送する特別な「ジャンプ」命令と「スキップ」命令によって影響を受ける場合があります。これらの条件付きジャンプとスキップが発生するかどうかは、値が別の値より大きい、小さい、または等しいなどの条件によって決まります。
アセンブリ言語

機械語をより人間に優しい形で表現したのがアセンブリ言語で、命令の数値を直接使用するのではなく、ニーモニックコードを使用して機械語命令を参照し、シンボル名を使用してストレージの場所やレジスタを参照することもあります。[3]たとえば、Zilog Z80プロセッサでは、CPUに汎用レジスタ00000101をデクリメントさせる機械語は、アセンブリ言語では と表現されます。[4]B DEC B
例
IBM 709x
IBM 704、709、704x、709x では、各命令ワードに 1 つの命令が格納されます。IBM では、ビットを左から S、1、...、35 と番号付けしています。ほとんどの命令は、次の 2 つの形式のいずれかになります。
- ジェネリック
- S,1-11
- 12-13 フラグ、一部の命令では無視される
- 14-17 未使用
- 18-20 タグ
- 21-35歳
- TSX以外のインデックスレジスタ制御
- S,1-2 オペコード
- 3-17 減少
- 18-20 タグ
- 21-35歳
IBM 7094および 7094 IIを除くすべてのモデルには、A、B、C と指定された 3 つのインデックス レジスタがあります。タグ内の複数の 1 ビットでインデックスを設定すると、選択したインデックス レジスタの論理和が減算され、タグ内の複数の 1 ビットでロードすると、選択したすべてのインデックス レジスタがロードされます。7094 および 7094 II には 7 つのインデックス レジスタがありますが、電源投入後は複数タグ モードになり、他の 4 つのインデックス レジスタにアクセスするには、複数タグ モード解除 ( LMTM ) 命令が必要です。
有効アドレスは通常 YC(T) です。ここで、C(T) は、タグが 0 の場合は 0、複数タグ モードの場合は選択されたインデックス レジスタの論理和、複数タグ モード以外の場合は選択されたインデックス レジスタのいずれかです。ただし、インデックス レジスタ制御命令の有効アドレスは Y のみです。
両ビットが 1 のフラグは間接アドレス指定を選択します。間接アドレス ワードにはタグと Y フィールドの両方があります。
これらのマシンには、転送(分岐) 命令に加えて、条件付きで 1 ワードまたは 2 ワードをスキップするスキップ命令があります。たとえば、Compare Accumulator with Storage (CAS) は 3 方向の比較を行い、結果に応じて NSI、NSI+1、または NSI+2 に条件付きでスキップします。
ミップス
MIPSアーキテクチャは、命令が常に32ビット長であるマシンコードの具体的な例を提供します。[5] : 299 命令の一般的なタイプは、最上位6ビットのop (操作)フィールドによって指定されます。Jタイプ(ジャンプ)およびIタイプ(即値)命令は、 opによって完全に指定されます。Rタイプ(レジスタ)命令には、正確な操作を決定するための追加フィールドfunctが含まれます。これらのタイプで使用されるフィールドは次のとおりです。
6 5 5 5 5 6 ビット [ op | rs | rt | rd |shamt| funct] R型 [ op | rs | rt | アドレス/即時] I型 [ op | ターゲットアドレス ] Jタイプ
rs、rt、rdはレジスタオペランドを示し、shamtはシフト量を示し、アドレスフィールドまたは即値フィールドにはオペランドが直接含まれる。[5] :299–301
例えば、レジスタ1と2を加算し、その結果をレジスタ6に格納する処理は次のようにエンコードされます: [5] : 554
[ op | rs | rt | rd |shamt| 機能]
0 1 2 6 0 32 小数点
000000 00001 00010 00110 00000 100000 バイナリ
レジスタ3にリストされている位置から68セル後のメモリセルから取得した値をレジスタ8にロードします: [5] : 552
[ op | rs | rt | アドレス/即時] 35 3 8 68 小数点 100011 00011 01000 00000 00001 000100 バイナリ
アドレス1024にジャンプ: [5] : 552
[ op | ターゲットアドレス ]
2 1024 10進数
000010 00000 00000 00000 10000 000000 バイナリ
重複する指示
可変長命令セット[6]を備えたプロセッサアーキテクチャ( Intelのx86プロセッサファミリなど)では、クラスカルカウントと呼ばれる制御フローの再同期現象の制限内で、[7] [6] [8] [9] [10]オペコードレベルのプログラミングを通じて、結果のコードを意図的に配置して、2つのコードパスがオペコードシーケンスの共通フラグメントを共有することが時々可能です。[注 1]これらは、重複命令、重複オペコード、重複コード、重複コード、命令切断、または命令の途中へのジャンプと呼ばれます。[11] [12] [13]
1970年代と1980年代には、メモリ空間を節約するために重複命令が使われることがありました。1つの例は、MicrosoftのAltair BASICのエラーテーブルの実装で、インターリーブされた命令が相互に命令バイトを共有していました。[14] [6] [11]この手法は現在ではほとんど使用されていませんが、ブートセクターに収まるブートローダーの実装など、バイトレベルでサイズの極端な最適化が必要な領域では、依然として頼らざるを得ない場合があります。[nb 2]
また、逆アセンブルや改ざんに対する対策として、コード難読化技術として使用されることもあります。[6] [9]
この原理は、複数の命令セットに互換性のないプロセッサ プラットフォームで実行する必要があるファット バイナリの共有コード シーケンスでも使用されます。 [注 1]
この特性は、既存のコードリポジトリ内のガジェットと呼ばれる意図しない命令を見つけるためにも使用され、リターン指向プログラミングでは、 return-to-libc攻撃などのエクスプロイトに対するコードインジェクションの代替として使用されます。[15] [6]
マイクロコードとの関係
一部のコンピュータでは、アーキテクチャのマシン コードは、マイクロコードと呼ばれるさらに基本的な基礎レイヤーによって実装され、基盤となるデータフローが大きく異なるコンピュータ モデルのラインまたはファミリー全体で共通のマシン言語インターフェイスを提供します。これは、異なるモデル間でのマシン言語プログラムの移植を容易にするために行われます。この使用例としては、IBM System/360ファミリーのコンピュータとその後継機が挙げられます。データフロー パスの幅は 8 ビットから 64 ビット以上ですが、それでもライン全体にわたってマシン言語レベルで共通のアーキテクチャを提供します。
マイクロコードを使用してエミュレータを実装すると、コンピュータはまったく異なるコンピュータのアーキテクチャを実現できます。System/360 ラインでは、これを使用して、以前の IBM マシンから新しいコンピュータ ファミリにプログラムを移植できるようにしました (例: IBM S/360 モデル 40 上の IBM 1401/1440/1460エミュレータ)。
バイトコードとの関係
マシン コードは、一般的にバイトコード(p コードとも呼ばれる)とは異なります。バイトコードは、インタープリタによって実行されるか、または高速 (直接) 実行のためにマシン コードにコンパイルされます。例外は、プロセッサが特定のバイトコードをマシン コードとして直接使用するように設計されている場合です。Javaプロセッサがこれに該当します。
マシンコードとアセンブリコードは、言語機能やライブラリのプラットフォーム依存部分を指すときにネイティブコードと呼ばれることがあります。 [16]
メモリに保存する
CPU の観点から見ると、マシン コードは RAM に保存されますが、通常はパフォーマンス上の理由からキャッシュ セットにも保存されます。アーキテクチャによっては、命令用とデータ用の異なるキャッシュが存在する場合があります。
CPU は、内部のプログラム カウンターに基づいて、どのマシン コードを実行するかを認識します。プログラム カウンターはメモリ アドレスを指し、プログラム分岐を引き起こす可能性のある特別な命令に基づいて変更されます。プログラム カウンターは通常、CPU が最初に電源投入されたときにハードコードされた値に設定され、このアドレスにあるマシン コードが実行されます。
同様に、プログラム カウンターは、有効なマシン コードではない場合でも、任意のアドレスにあるマシン コードを実行するように設定できます。これにより、通常、アーキテクチャ固有の保護エラーが発生します。
ページング ベースのシステムでは、多くの場合、ページ パーミッションによって、現在のページが実行ビットによって実際にマシン コードを保持しているかどうかが CPU に通知されます。ページには、さまざまなハウスキーピング機能のために、複数のパーミッション ビット (読み取り可能、書き込み可能など) があります。たとえば、Unix 系システムでは、メモリ ページをシステム コールで実行可能に切り替えることができmprotect()、Windows では、VirtualProtect()を使用して同様の結果を得ることができます。実行可能でないページでマシン コードを実行しようとすると、通常、アーキテクチャ固有の障害が発生します。データをマシン コードとして扱うこと、またはさまざまな手法で既存のマシン コードを使用する新しい方法を見つけることは、セキュリティの脆弱性の根底にあります。
同様に、セグメント ベースのシステムでは、セグメント記述子は、セグメントに実行可能コードを含めることができるかどうか、およびそのコードがどのリングで実行できるかを示すことができます。
プロセスの観点から見ると、コード空間は、実行中のコードが格納されるアドレス空間の一部です。マルチタスクシステムでは、これはプログラムのコード セグメントと通常は共有ライブラリで構成されます。マルチスレッド環境では、1 つのプロセスの異なるスレッドがデータ空間とともにコード空間を共有するため、プロセス切り替えと比較して コンテキスト切り替えのオーバーヘッドが大幅に削減されます。
人間による可読性
マシン コードを対応するソース コードにデコードするためのさまざまなツールと方法が存在します。
アセンブリ言語は機械語と1対1でマッピングされるため、機械語は対応するアセンブリ言語のソースコードに簡単にデコードできます。 [17]アセンブリ言語のデコード方法は逆アセンブリと呼ばれます。
マシンコードは、次の 2 つの条件下で、対応する高級言語にデコードできます。
最初の条件は、ソース コードの難読化された読み取りを受け入れることです。マシン コードがソース言語の 逆コンパイラに送信されると、ソース コードの難読化されたバージョンが表示されます。
2 番目の条件では、マシン コードに、その中にエンコードされたソース コードに関する情報が含まれている必要があります。この情報には、デバッグ シンボルを含むシンボル テーブルが含まれます。シンボル テーブルは実行可能ファイル内に格納される場合もあれば、別のファイルに存在する場合もあります。デバッガーはシンボル テーブルを読み取り、プログラマが実行中のマシン コードを対話的にデバッグできるようにします。
- IBM 709、IBM 7090、およびIBM 7094コンピュータ用のSHAREオペレーティング システム(1959) では、 SQUOZEというロード可能なコード形式が許可されていました。SQUOZE はアセンブリ言語コードの圧縮バイナリ形式で、シンボル テーブルが含まれていました。
- z/OSなどの現代のIBMメインフレームオペレーティングシステムには、関連データ(ADATA)と呼ばれるシンボルテーブルが用意されています。このテーブルは、IBM高水準アセンブラ(HLASM) [18]、IBMのCOBOLコンパイラ[19]、およびIBMのPL/Iコンパイラ[20]によって生成できるファイルに格納されます。
- Microsoft Windowsでは、プログラムデータベース( )ファイル[22]に格納されるシンボルテーブル[21]が利用可能です。
.pdb - ほとんどのUnix 系オペレーティング システムには、stabsおよびDWARFというシンボル テーブル形式が用意されています。macOSおよびその他のDarwinベースのオペレーティング システムでは、デバッグ シンボルは別のファイルに DWARF 形式で保存されます。
.dSYM
参照
- アセンブリ言語
- エンディアン
- 機械言語の一覧
- マシンコードモニター
- オーバーヘッドコード
- Pコードマシン
- 縮小命令セットコンピュータ(RISC)
- 非常に長い命令語
- 機械コードの教育: Micro-Professor MPF-I
注記
- ^ ab 可変長命令セットを持つプロセッサ アーキテクチャ上の重複命令は、制御フローの再同期によって異なるコード パスを 1 つにマージするように調整できる場合がありますが、異なるプロセッサ アーキテクチャの重複コードは、ファット バイナリで使用されることがあるように、基盤となるプロセッサに応じて実行パスが異なる方向に分岐するように作成される場合もあります。
- ^ たとえば、DR-DOS の マスター ブート レコード(MBR) とブート セクタ(パーティション テーブルとBIOS パラメータ ブロックも保持し、コード用にそれぞれ 446 バイトと 423 バイト未満を残す) は、従来、FAT12またはFAT16 ファイル システムでブート ファイルを自動的に見つけ、それをまとめてメモリにロードできました。これに対し、DOS、MS-DOS、PC DOSでは、システム ファイルがファイル システムの最初の 2 つのディレクトリエントリ位置を占め、 IBMBIO.COMの最初の 3 つのセクタが、ファイルの残りの部分をメモリにロードするためのセカンダリ ローダーを含む連続セクタのデータ領域の先頭に格納される必要があります (これらの条件をすべて処理するにはSYSが必要です)。FAT32と論理ブロック アドレス指定(LBA) のサポートが追加されたとき、 Microsoft はコード サイズ上の理由からi386命令を必要とし、ブート コードを 2 つのセクターに分割するように切り替えましたが、これは DR-DOS では採用できないオプションでした。マルチブートやチェーン ロードのシナリオで、また古いIBM PC 互換PCと同様に、他のオペレーティング システムとの後方互換性と相互互換性が失われるからです。代わりに、DR-DOS 7.07 のブート セクターは、自己変更コード、マシン語でのオペコードレベルのプログラミング、(文書化された)副作用の制御された利用、マルチレベルのデータ/コード オーバーラップ、アルゴリズムによる折りたたみ手法に頼って、拡張機能を一切犠牲にすることなく、すべてをわずか 512 バイトの物理セクターに収めました。
参考文献
- ^ Stallings, William (2015).コンピュータの構成とアーキテクチャ 第 10 版. Pearson Prentice Hall. p. 776. ISBN 9789332570405。
- ^ Kjell, Bradley. 「即時オペランド」。
- ^ ドゥーリッシュ、ポール(2004)。アクションがどこにあるのか:具体化されたインタラクションの基礎。MITプレス。p . 7。ISBN 0-262-54178-5. 2023年3月5日閲覧。
- ^ Zaks, Rodnay (1982). Programming the Z80 (Third Revised ed.). Sybex . pp. 67, 120, 609. ISBN 0-89588-094-6. 2023年3月5日閲覧。
- ^ abcdeハリス、デビッド; ハリス、サラ L. (2007) 。デジタルデザインとコンピュータアーキテクチャ。Morgan Kaufmann Publishers。ISBN 978-0-12-370497-9. 2023年3月5日閲覧。
- ^ abcde Jacob, Matthias; Jakubowski, Mariusz H.; Venkatesan, Ramarathnam [Wikidata にて] (2007 年 9 月 20 ~ 21 日)。 インテグラル バイナリ実行に向けて: オーバーラップ命令エンコーディングを使用したオブリビアス ハッシュの実装(PDF)。 第 9 回マルチメディアとセキュリティに関するワークショップ (MM&Sec '07) の議事録。 ダラス、テキサス州、米国: Association for Computing Machinery。 pp. 129 ~ 140。CiteSeerX 10.1.1.69.5258。doi :10.1145/1288869.1288887。ISBN 978-1-59593-857-2. S2CID 14174680. 2018年9月4日にオリジナルからアーカイブ(PDF)されました。2021年12月25日に取得。(12ページ)
- ^ ラガリアス、ジェフリー・「ジェフ」・クラーク、レインズ、エリック・マイケル、ヴァンダーベイ、ロバート・J. (2009) [2001-10-13]。 ブラムス、スティーブン、ゲーライン、ウィリアム・V.、ロバーツ、フレッド・S. (編)。「クラスカル・カウント」。選好、選択、秩序の数学。ピーター・J・フィッシュバーンを讃えるエッセイ集。ベルリン/ハイデルベルク、ドイツ:シュプリンガー・フェアラーク:371–391。arXiv:math/0110143。ISBN 978-3-540-79127-0。(22ページ)
- ^ Andriesse, Dennis; Bos, Herbert [Wikidata にて] (2014-07-10)。オランダ、アムステルダム自由大学で執筆。Dietrich, Sven (編)。隠れたトリガーベースのマルウェアに対する命令レベルステガノグラフィ(PDF)。侵入とマルウェアの検出、脆弱性評価に関する第 11 回国際会議(DIMVA)。コンピュータサイエンスの講義ノート。イギリス、エガム、スイス: Springer International Publishing。pp . 41–50 [45]。doi :10.1007 / 978-3-319-08509-8_3。eISSN 1611-3349。ISBN 978-3-31908508-1. ISSN 0302-9743. S2CID 4634611. LNCS 8550. 2023年8月26日時点のオリジナルよりアーカイブ(PDF) . 2023年8月26日閲覧。(10ページ)
- ^ ab Jakubowski, Mariusz H. (2016 年 2 月)。「ソフトウェア改ざん防止のためのグラフ ベース モデル」。Microsoft。2019年10 月 31 日時点のオリジナルよりアーカイブ。2023年 8 月 19 日に取得。
- ^ Jämthagen, Christopher (2016 年 11 月). ソフトウェア セキュリティにおける攻撃的および防御的方法について(PDF) (論文). ルンド、スウェーデン:ルンド大学電気情報技術学部. p. 96. ISBN 978-91-7623-942-1. ISSN 1654-790X. 2023年8月26日時点のオリジナルよりアーカイブ(PDF) . 2023年8月26日閲覧。(1+xvii+1+152ページ)
- ^ ab 「x86 上の意図しない命令」。Hacker News。2021年。2021年12月25日時点のオリジナルよりアーカイブ。2021年12月24日閲覧。
- ^ キンダー、ヨハネス (2010-09-24)。 x86 実行可能ファイルの静的解析 [ x86 Maschinensprache におけるプログラムの統計解析] (PDF) (論文)。ミュンヘン、ドイツ:ダルムシュタット工科大学。 D17. 2020年11月12日のオリジナルからアーカイブ。2021年12月25日閲覧。(199ページ)
- ^ 「「重複命令」難読化とは何ですか?」Reverse Engineering Stack Exchange 2013-04-07。2021-12-25にオリジナルからアーカイブ。2021-12-25に取得。
- ^ ゲイツ、ウィリアム「ビル」ヘンリー、個人的なコミュニケーション(注:Jacob らによる)
- ^ Shacham, Hovav (2007). The Geometry of Innocent Flesh on the Bone: Return-into-libc without Function Calls (on the x86) (PDF) . Proceedings of the ACM, CCS 2007. ACM Press . 2021-12-15 にオリジナルからアーカイブ(PDF)されました。2021-12-24に取得。
- ^ 「マネージド、アンマネージド、ネイティブ: これはどのようなコードですか?」。developer.com。2003年 4 月 28 日。2008年 9 月 2 日閲覧。
- ^ Tanenbaum, Andrew S. (1990). Structured Computer Organization, Third Edition. Prentice Hall . p. 398. ISBN 978-0-13-854662-5。
- ^ 「関連データアーキテクチャ」。高レベルアセンブラおよびツールキット機能。
- ^ 「COBOL SYSADATA ファイルの内容」。Enterprise COBOL for z/OS。
- ^ 「SYSADATA メッセージ情報」。Enterprise PL/I for z/OS 6.1 の情報。
- ^ 「Windows デバッグ用のシンボル」。Microsoft Learn . 2022-12-20。
- ^ 「.Pdb ファイルのクエリ」。Microsoft Learn。2024 年 1 月 12 日。
さらに読む
- ヘネシー、ジョン L.、パターソン、デビッド A. (1994)。コンピュータの構成と設計。ハードウェア/ソフトウェア インターフェイス。Morgan Kaufmann Publishers。ISBN 1-55860-281-X。
- Tanenbaum, Andrew S. ( 1999)。構造化コンピュータ組織。Prentice Hall。ISBN 0-13-020435-8。
- Brookshear, J. Glenn (2007)。『コンピュータサイエンス:概要』。Addison Wesley。ISBN 978-0-321-38701-1。
参照
- {{コンピュータ言語}}
- {{プログラミング言語}}
- {{プログラミングパラダイム navbox }}
