モトローラ MC6800 のアセンブリ言語のソースコード
アセンブリ言語 (アセンブリげんご、英 : assembly language 、アセンブリ )はビット列命令 に対応した文字列命令を利用する低水準 プログラミング言語 の総称である[ 1] 。
アセンブラ (英 : Assembler )またはアセンブラ言語 (英 : Assembler Language )とも呼ばれる[ 注 1] [ 2] 。
概要
プロセッサ は機械語 プログラムを直接読み取り実行する。しかし人間にとってビット列は直観的に理解しづらいため、機械語コーディングは容易でない。これを解決するために、ビット列に対応する文字列命令(ニーモニック )を利用するプログラミング言語の総称がアセンブリ言語 である[ 1] 。
アセンブリ言語を用いることで、機械語相当の低水準 なコードをより直観的に記述できる。高度なアセンブリ言語ではアセンブラに対する命令(疑似命令)やマクロ を用いて、より抽象的な記述が可能である[ 注 2] 。パイプライン処理 などを最適化するために命令順序を入れ替えたり、ラベルの位置関係によってアドレッシングモードを最適化するアセンブラもあり、必ずしもソーステキストの記述とアセンブルの結果が直接対応するとは限らない。
アセンブリ言語は機械語と強く結びついているため、各プロセッサ向けに仕様の異なる様々な(具体的な)アセンブリ言語が存在する(「アセンブリ言語」は総称である)。同じ命令セット に対しても複数のアセンブリ言語が存在しうる(例: GNU アセンブラのgasのインテル プロセッサ用)。
アセンブリ言語の基本文法として、1つの命令は1つのニーモニック と0個以上のオペランド からなる。プログラム全体はニーモニック/オペランド列、ディレクティブや擬似命令と呼ばれるメタな文、コメント、データで構成されている。通常の文はオペコードのニーモニックで始まり、パラメータ(データ、引数)のリストがそれに続く[ 3] 。多くのアセンブリ言語はオペランドのアドレスや定数をラベル・シンボルで記述できハードコーディング を避けられる。
基本文法
アセンブラの開発者によって用語の使い方に大きな差異があり、文の分類などが異なる。例えば、マシンのニーモニックや拡張ニーモニック以外は全て擬似命令と呼ぶ場合もある。典型的なアセンブリ言語は、プログラムの操作の定義に使われる命令文をニーモニック、データセクション、アセンブリディレクティブの3種類に分類する。
ニーモニック
ニーモニック (英 : mnemonic )は処理内容に応じて各機械語命令に与えられた文字列・命令語である[ 4] 。機械語のオペコード に相当する。
ビット列である機械語はその処理が直観的にわからないため、機械語コーディングは容易でない。人間がより容易に機械語と同等なコードを書くため、ビット列を意味ある文字列で表現するニーモニックが発明された[ 4] 。例えばX64 機械語 0x05
は「整数の加算」を意味するのでニーモニック ADD
を対応させる。個々の機械語命令には少なくとも1つのニーモニックが対応する。
拡張ニーモニック は命令の特殊な用途をサポートするのに使われることが多く、本来の命令の名称からはその用途が連想できないときに使うことが多い。例えば、多くのCPUは明示的にNOP 命令を用意していないが、その用途に使える命令は存在する。8086ではxchg ax,ax という命令がnop として使えるので、アセンブリ言語でnop を記述すると xchg ax,ax という命令に変換される。逆アセンブラにもこのあたりを認識し、xchg ax,ax をnop に変換するものがある。同様にIBMのSystem/360 とSystem/370 のアセンブラでは、拡張ニーモニックNOP とNOPR を使用し、それぞれBC とBCR のマスク0の命令に変換する。SPARC アーキテクチャでは、拡張ニーモニックをsynthetic instructions と呼んでいる[ 5] 。
命令は一般に「オペコード」と0以上の「オペランド」で構成される。多くの命令は1つまたは2つの値を参照する。オペランドには即値(命令内に置かれる値)、レジスタ(暗黙のうちに使用される場合もある)、記憶装置内のデータの位置を示すアドレスなどがある。「拡張ニーモニック」はオペコードと特定オペランドの組合せを表すのに使われることが多い。例えば、System/360では、BC命令にマスク15を組み合わせたものがB 、BC命令にマスク0を組み合わせたものがNOP という拡張ニーモニックで表される。オペランドの順序(例: ソースとディスティネーションの前後)は言語に依る。
オペランド
オペランド (英 : operand 、被演算子 )は命令の対象・引数である。1つの命令では、ニーモニックに続き0個以上のオペランドが記述される。オペランドにはソースとデスティネーションの二種類があり、データとして読み取られるのがソースで、オペコードで示された命令の実行結果が格納されるのがデスティネーションである。ソースには定数・レジスタ・メモリのいずれか、デスティネーションにはレジスタ・メモリのいずれかを指定する。
データセクション
データと変数を保持するデータ要素を定義するのに使われる命令文がある。データの型、長さ、境界(アライメント)を定義する。また、そのデータがプログラム外部(別ファイルでアセンブルされたプログラム)からも利用可能なのか、それともデータセクションを定義したプログラム内でのみ使用可能なのかも定義できる。一部のアセンブラはこれを擬似命令に分類している。
アセンブリディレクティブ
アセンブリディレクティブは、擬似命令とも呼ばれ、アセンブラがアセンブリ実施中に実行すべき命令となっている[ 6] 。プログラマが入力するパラメータによって、異なった形でアセンブルが行われるよう指示することができる。また、プログラムの見た目を操作して、可読性 と保守性を向上させるのにも使われる。例えば、記憶装置の領域を予約し、その初期内容を指定するディレクティブなどがある。ディレクティブの名称はドットで始まることが多く、それによって通常のニーモニックと区別している。
擬似オペコード(pseudo-opcode)と言った場合、オブジェクトコードを実際に生成するディレクティブのみを指すこともある[ 7] 。
ラベル/シンボル
シンボリックアセンブラでは、任意の名前(ラベル またはシンボル)とメモリ位置を対応付けることができる。通常、定数や変数に名前をつけることができ、命令文ではそれらの位置を名前で参照できる。実行コードではサブルーチンのエントリポイントと名前を関連付け、サブルーチンを名前で呼び出すことができる。サブルーチン内では、分岐命令の分岐先をラベルで示すことができる。一部のアセンブラは「ローカルシンボル」をサポートしており、通常のシンボルとは語彙的に区別する(例えば、"10$"を分岐先に使用する、など)。
一部のアセンブラは柔軟なシンボル管理を提供しており、複数の名前空間 を管理したり、データ構造 内のオフセットを自動的に計算したり、リテラル値やアセンブラが実施した単純な計算結果を参照するラベルを割り当てたりすることができる。ラベルは定数や変数をリロケータブル なアドレスで初期化するのにも使える。
例
x86 /IA-32 プロセッサにおいて8ビット即値 をレジスタ に入れる命令を例にとる。
この命令のバイナリコードは 10110 で、その後に3ビットのレジスタを指定する識別子が続く。AL レジスタの識別子は 000 なので、次に示す機械語 は AL レジスタに 01100001 というデータをロードする[ 8] 。
10110000 01100001
このバイナリコードを人間が読みやすいように十六進法 で表現すると次のようになる。
B0 61
ここで、B0
は「AL に後続の値をコピーする」ことを意味し、61
は01100001を十六進法で表したもの(十進法 では97)である。インテルのアセンブリ言語では、この種の命令に MOV というニーモニックを割り当てており、セミコロン以下に説明的コメントを添えたアセンブリ言語での表現は次のようになる。
MOV AL , 61 h ; Load AL with 97 decimal (61 hex)
この場合、定数61Hがソース、レジスタALがデスティネーションに該当し、命令が実行されると、定数61Hが、レジスタALに単純に格納される。これが人間にとってはさらに読みやすく覚えやすい。
前述のインテルの MOV のようにデータの転送の多くを同一の命令あるいはニーモニックとする場合もあれば、データのコピー/移動の方向などによって別々の命令あるいはニーモニックとする場合もある(「メモリからレジスタへの移動」を L、「レジスタからメモリへの移動」を ST、「レジスタからレジスタへの移動」を LR、「即値をメモリへ移動」を MVI など)。(この段落では命令セットの設計の話とアセンブリ言語の話を一緒にしている)
インテルのオペコード 10110000(B0
)は8ビットの値を AL レジスタにコピーするが、10110001(B1
)はCL レジスタにコピーし、10110010(B2
)は DL レジスタにコピーする。これらをアセンブリ言語で表現すると次のようになる[ 8] 。
MOV AL , 1 h ; Load AL with immediate value 1
MOV CL , 2 h ; Load CL with immediate value 2
MOV DL , 3 h ; Load DL with immediate value 3
MOVの構文には次の例のようにさらに複雑なものもある[ 9] 。
MOV EAX , [ EBX ] ; Move the 4 bytes in memory at the address contained in EBX into EAX
MOV [ ESI + EAX ], CL ; Move the contents of CL into the byte at address ESI+EAX
MOVというニーモニックを使った文は、その内容によってアセンブラが88-8E、A0-A3、B0-B8、C6、C7のいずれかのオペコードに変換するので、プログラマはオペコードを知る必要がないし、オペコードを覚える必要もない[ 8] 。
高級言語との違い
アセンブリ言語は低水準 プログラミング言語 であり、C言語 などの高級言語 より抽象度が低い。すなわち言語機能(構文や型)が少ない。次の表は「基本的なアセンブリ言語」と高級言語の間にある言語機能差である。
この差はあくまで言語機能の差である。「高級言語でのみ可能、アセンブリ言語では不可」という意味ではない。例えばアセンブリ言語に関数構文は存在しないが関数に相当するパターンが存在する(関数プロローグ・エピローグ (英語版 ) )。より正確な言い方をすれば、アセンブラで頻出するパターンを1つの機能として言語仕様に組み込んで抽象度を上げていった言語が高級言語である。
高水準文法
より抽象化され少ないコード量でアセンブラを書くために様々な高水準文法がアセンブリ言語に導入されてきた。現在では高水準化のメインストリームは高級言語 に移った一方[ 11] 、目的に応じてアセンブリ言語を選択するユーザー向けに高機能なアセンブリ言語の開発も続いている[ 12] 。
マクロ
アセンブリ言語においてもマクロ が利用される。一般的なマクロと同様、高度なアセンブラマクロでは制御構文導入・引数展開・ユーザー定義マクロ適用などが可能である。文字列であるオペコード・ニーモニックはマクロの対象となるため、これを利用して疑似ニーモニックによる記述も可能になる。
例えば、一部のZ80 用アセンブラでは、ld hl,bc というマクロ命令を ld l,c と ld h,b という2命令に展開する[ 13] 。メインフレームの時代には、マクロは特定顧客の大規模ソフトウェアシステムのカスタマイズや、メーカーのオペレーティングシステムを顧客の要望に合わせた特注版にするのに使われていた。IBM の VM/CMS 、リアルタイムトランザクション処理用アドオン、CICS 、ACP (英語版 ) /TPF [ 14] などで使われてきた。
制御構造
構造化プログラミング の要素を取り入れたアセンブラもある。最初期には "Concept-14 macro set" がSystem/360のマクロアセンブラにIF/ELSE/ENDIFなどの制御構造を導入した[ 15] [ 16] 。また8080/Z80 プロセッサ向けの A-natural ではブロック構造や命令実行順序の制御が採用された。
また構造化プログラミングとは若干異なるが、キャリーラボ はBASIC 風の文法のアセンブリ言語 BASE を開発した。Z80 用のBASE-80とMC6809 用のBASE-09がある。BASEの表記例は下記の通り(BASE-09)。
S [ A , B , X , U
A = $ 80
A = A + $ C0
S ] A , B , X , U , PC
上記の記述は下記のアセンブラ表記に対応する。
PSHS A , B , X , U
LDA #$80
ADDA #$C0
PULS A , B , X , U , PC
アセンブラ
アセンブル (英 : assemble )はアセンブリ言語で書かれたプログラムから機械語で書かれたオブジェクトコード への変換である。具体的には、ニーモニックをオペコード に変換しシンボル名 をメモリ位置や他の実体に変換する[ 6] 。
アセンブルは比較的単純な規則からなるため、人の手でも実行できる(ハンドアセンブル )。単純な作業を効率良くミス無く行うのはプログラムの得意分野であり、そのようなソフトウェアが開発された。このアセンブリをおこなうプログラムをアセンブラ (英 : assembler )という。初期にはアセンブリプログラムとも呼ばれた[ 17] 。
シンボル名による参照の利用はアセンブラの重要な機能であり、面倒な計算やプログラム修正に伴うアドレスの更新の手間を省くことができる。また、オブジェクトコードを生成する際、ローダ用情報も併せて生成するアセンブラもある[ 18] 。マクロを含むアセンブリ言語に対応している場合、処理系にはm4 のような汎用プロセッサあるいはプロセッサ内蔵アセンブラ(マクロアセンブラ )が利用される[ 19] 。ポリモーフィズム 、継承 [ 8] などをもつ高水準アセンブリ言語に対応したアセンブラは高水準アセンブラ (英語版 ) と呼ばれる[ 20] 。
動作プラットフォーム以外のターゲットプラットフォームを選択できるアセンブラはクロスアセンブラ とも呼ばれる(参考: クロスコンパイラ )。メタアセンブラ は、アセンブリ言語の文法や意味論を記述したものを入力とし、その言語のためのアセンブラを出力するプログラムである[ 21] 。
逆方向の変換、すなわちオブジェクトコードのアセンブリ言語化をおこなうプログラムを逆アセンブラ という。
分類
アセンブラは様々な観点から分類できる。パス回数(アセンブル時のソースファイル走査回数)の観点ではワンパスアセンブラ とマルチパスアセンブラ に分類できる。
ワンパスアセンブラ
ソースコードを1回だけパスするアセンブラ。定義される前にシンボルが使われているとオブジェクトコードの最後に "errata" を置く必要があり、リンカ またはローダ が未定義シンボルが使われていた位置にあるプレースホルダーを書き換える。あるいは、未定義なシンボルを使用するとエラーになる。
マルチパスアセンブラ
最初のパスで全シンボルとその値の表を作成し、その表を使ってその後のパスでコードを生成する。
どちらの場合も、アセンブラは最初のパスで各命令のサイズを確定させる必要があり、それによって後に出現するシンボルのアドレスを計算する。命令のサイズは後から定義されるオペランドの型や距離に依存することがあるため、アセンブラは最初のパスでは悲観的な見積もりをし、必要に応じてその後のパスまたは errata にて1つ以上のNOP 命令(何もしない命令)を挿入してすき間を埋める必要がある。最適化を行うアセンブラでは、最初の悲観的コードをその後のパスで稠密なコードに書き換えてアドレスの再計算を行うことがある。
もともとワンパスアセンブラは高速であるためよく使われていた。マルチパス動作をするには、磁気テープ を巻き戻したりパンチカード のデッキをセットし直して読み込む必要があったためである。現代のコンピュータではマルチパスであってもそのような遅延は生じない。マルチパスアセンブラは errata がないため、リンク処理 (アセンブラが直接実行コードを生成する場合はローダ の処理)が高速化される[ 22] 。
主なアセンブラ
Unix系 システムでは、アセンブラを as と呼ぶのが一般的だが、実体はそれぞれのOSで異なる。GNUアセンブラ を使っているものが多い。
同じ系統のプロセッサであっても、複数のアセンブリ言語の方言が存在する。アセンブラによっては他の方言のアセンブリ言語も使用可能な場合がある。例えば、TASM はMASM 用コードを入力として受け付け可能だが、逆は不可能である。FASM (英語版 ) とNASM は文法がほぼ同じだが、サポートしているマクロが異なるため、相互の翻訳は困難である。いずれも基本機能は同じだが、追加機能に差異がある[ 23] 。
歴史
アセンブリ言語は、ごく単純なものまで含めれば、プログラム内蔵方式 のコンピュータの最初期の1940年代から存在している。世界で最初に実用的に稼働したノイマン型 電子計算機とされるEDSAC (1949) の initial orders (現代の用語ではブート ローダーに相当するもの)は、テープにパンチされた十進によるアドレスを、内部表現の二進に変換するなどの機能を持っていた(命令については、「1文字のニーモニック」に見えるかもしれないが、それは実際には同機の機械語そのものである)[ 24] 。ナサニエル・ロチェスター は1954年に IBM 701 用アセンブラを書いている。1955年、Stan Poley が IBM 650 用言語アセンブリSOAP (Symbolic Optimal Assembly Program) を開発した[ 25] 。
コンピュータの歴史の初期には、このような、プログラムによって機械語プログラムを生成することを自動プログラミング と呼んだ。
ドナルド・ギリース は、まだ発明されていなかったアセンブラを開発中に、フォン・ノイマン から開発を即座に止めるように言われた、という1950年代初期ならではの逸話がある。当時は、人間が手作業でもできるような瑣末な仕事をコンピュータにさせるような時代が来るとは考えられておらず、単に時間の無駄だとノイマンは考えたのである。
歴史的には多数のプログラム(OSやアプリケーション)がアセンブリ言語だけで書かれてきた。ALGOL の方言であるESPOL で書かれた Burroughs MCP (1961) が登場するまで、オペレーティングシステムはアセンブリ言語で書くのが普通だった。IBM のメインフレーム 用ソフトウェアの多くはアセンブリ言語で書かれていた。COBOL 、FORTRAN 、PL/I などが取って代わっていったが、1990年代になってもアセンブリ言語のコードベースを保守し続けていた大企業も少なくない。
初期のマイクロコンピュータ でも同様に広く用いられた。これは、リソースの制約が厳しく、メモリやディスプレイのアーキテクチャが特殊だったからである。また、マイクロコンピュータ向けの高水準言語のコンパイラがなかったという面も重要である。また、初期のマイクロコンピュータのユーザは趣味としての使用が主であり、何でも自前で作るという精神もそれに影響していたと見られる。
1980年代から1990年代にかけて、ホームコンピュータ (ZX Spectrum 、コモドール64 、Amiga 、Atari ST など)でもアセンブリ言語がよく使われていた。というのもそれらのBASICは性能が低く、ハードウェアの全機能を利用できないことが多かったためである。例えば、Amigaにはフリーウェア のアセンブリ言語統合開発環境 ASM-One assembler があり、Microsoft Visual Studio に匹敵する機能を備えていた。
Don French が開発した VIC-20 用アセンブラは 1,639 バイトという小ささで、世界一小さいアセンブラと言われている。アドレスをシンボルで表現でき、各種アドレス計算(四則演算、AND、OR、冪乗など)が可能だった[ 26] 。
1980年代のビジネスソフトでは、例えば表計算ソフト Lotus 1-2-3 などはアセンブリ言語で書かれていた。日本では松 などが該当[ 27] する。
1990年代に入っても、コンシューマーゲーム の多くはアセンブリ言語でプログラムが書かれていた。しかしゲーム内容が複雑化し、プログラムの規模が増大するにつれて、アセンブラでは開発が困難となり、高水準言語による開発が主流となっていった。例えばプレイステーション ではGCC が公式のSDKに含まれていて、標準の開発言語はC言語 であった[ 28] [ 29] 。この時代のゲーム機は3次元コンピュータグラフィックス の積極的な導入が始まっており、ハードウェア性能も向上したことから、C言語による開発も十分可能となったが、コンパイラの最適化能力が未成熟だったこともあいまって、ハードウェア性能を最大限引き出すにはアセンブリ言語を駆使した手動最適化や細かなチューニングが必要となることも多かった。セガサターン の最高性能を引き出してプレイステーション に対抗するには、アセンブリ言語を使うしかなかったと述べていた業界関係者もいた[ 30] 。ただし一方で、ファミコン 時代すでにメタルスレイダーグローリー やスーパーファミコン のMOTHER 2 ・シムシティ [ 31] 、プレイステーションのクラッシュ・バンディクー で[ 32] 、開発の一部にLISP が使われていたという話もあり、当時のコンシューマーゲームの分野ではアセンブリ言語やC言語が全てだったというわけではない。
2000年代初頭、マイクロソフト は原始的なプログラマブルシェーダー に対応したDirectX (Direct3D ) 8.0をリリースした。このDirect3D 8.0におけるシェーダープログラムは、グラフィックスハードウェアに依存しない中間言語(バイトコード)を出力することのできるアセンブリ言語(シェーダーアセンブラ)を使用して記述するものだった。2001年には世界で初めてプログラマブルシェーダーに対応したコンシューマーゲーム機として初代Xbox が登場したが、このXboxに搭載されていたグラフィックスAPIもDirect3D 8.x相当のカスタマイズ版[ 33] であり、CPU上で実行するホストプログラム(ゲームアプリケーション本体のコード)はC++ を使って記述する一方、GPU 上で実行するシェーダープログラムの記述にはアセンブラを使用していた。のちにHLSL やCg (C for Graphics) といった高水準シェーディング言語が開発され、HLSLに対応したDirect3D 9.0以降はシェーダープログラムも高水準言語を利用して記述するようになった。Direct3D 10のシェーダーモデル4.0以降は、シェーダーアセンブラではなくHLSLの使用が必須となっている[ 34] 。
現在の最適化コンパイラ は人手で書かれたアセンブリ言語のコードと同等の性能を発揮すると言われている[ 35] (例外もある[ 36] [ 37] [ 38] )。最近 [いつ? ] のプロセッサやメモリサブシステムは複雑化してきたため、コンパイラでもアセンブリ言語でも効果的な最適化がますます困難になってきている[ 39] [ 40] 。さらにプロセッサが高性能化し律速が入出力 やページング へ移ることで、コーディングが性能向上に貢献するケースは以前より少なくなっている。
一方C++ やC# のような、Cよりもさらに高水準の言語が主流になってからも、コンパイラが出力したアセンブリコードを解析して最適化やチューニングの余地を探るといった手法は一般的に行なわれている[ 41] 。
利用
低水準 言語 であるアセンブラはC言語 などの高級言語 と異なる領域で利用される。
目的
アセンブラを用いる目的として以下が挙げられる。
高速: レジスタ利用やループ展開の最適化
省フットプリント: ランタイムや標準ライブラリの排除
リアルタイム(時間的正確性): GC スパイク、ページフォルト 、プリエンプション の排除
ハードウェア操作
高級言語非対応命令の利用
挙動理解
事例
アセンブリ言語が用いられる事例として以下が挙げられる。
組み込みシステム : 省フットプリントでのハードウェア操作が目的
電話機のファームウェア
自動車の燃料・点火システム
センサー
デバイスドライバ や割り込みハンドラ 、ブートコード 、BIOS 、POST
ハードウェアないしはファームウェアの呼び出し規約をアセンブリ言語によりカーネルやドライバにて使用している高級言語の規約へ変換することにより、主要な機能を高級言語で実装することができる。
暗号 化: 高級言語非対応命令の使用が目的
数値計算: 高速化が目的
リアルタイムシステム : リアルタイム性が目的
暗号アルゴリズムは常に厳密に同じ時間で実行することで、タイミング攻撃 を防ぐ。
高度なセキュリティが要求され、環境を完全に制御する必要がある場合。
監視・トレース・デバッグ のための命令セットシミュレータ で、追加のオーバーヘッドを最小に保ちたい場合。
リバースエンジニアリング : 挙動理解が目的
デバッグ: 例 - コンパイラ最適化の確認
ソフトウェア改造: 例 - 商用コンピュータゲーム の改造
ハッキング: 例 - コピープロテクト 解除
学習: コンピュータの理解
自己書き換えコード
コードサイズの上限に制限がある環境
ブートセクタ に格納するブートローダ 。例として、MBR では最大446バイト。
トラップ処理やシグナル ハンドラ起動などのために、カーネルがプロセスのアドレス空間へ見せるコード。vDSO を用い、プロセスからはシェアードオブジェクトを読み込んだように見せる実装が多い。
見せるコードの範囲を正確に把握する必要があるため、コードのエントリだけでなく終了部にもラベルを与える。アセンブリ言語では容易だが、高級言語では一般に不要な機能なのでサポートされていない。
元来はユーザモード用のスタック上にカーネルからコードをコピーして実行していた。欠点として、スタックはユーザモードでの書き込みが禁止できず、スタック上でのコード実行がセキュリティホールとしてしばしば利用されたことから、実装方法の変更が進められている。
オブジェクトファイル に依存した機能
コンパイラが通常は使用しないセクション等にシンボルを定義することができる。例として、Linuxカーネル ではモジュール へ公開するシンボルをマクロEXPORT_SYMBOL
(ないしはその派生)[ 43] へ与える。このマクロは、インラインアセンブリを用いてオブジェクトファイルのセクション.export_symbol
へシンボルの情報を追加し、モジュールローダがシンボル解決にて使用できるようにする。マクロの内容はCPUアーキテクチャには依存せず、その定義もCPUアーキテクチャに依存しないヘッダファイル(include/linux/export.h
)[ 注 3] にあるが、C言語を含め高級言語のみでの実装が難しく、アセンブリが適している。[ 注 4]
なお一方で、最近 [いつ? ] のコンピュータの命令セットはその多くはどれも似ている。したがって、どれか1つのアセンブリ言語を学ぶだけで、基本概念、どんなときにアセンブリ言語を使用するのが適しているか、高水準言語から効率的な実行コードを生成する方法をある程度は学習できる[ 44] 。
高水準言語との連携
高水準言語の処理系の呼出規約 (言語処理系ではなくOSやハードウェアベンダ側で共通化している場合もある)に従うことで、高水準言語と相互にコードを呼び出すことができる。後述のインラインアセンブラ などにより同一のモジュールに埋め込むこともできれば、別モジュールとしてリンケージエディタ でリンクすることもある。
多くのコンパイラは、機械語を直接生成するのではなく、アセンブリ言語のコードを生成し、それをアセンブラに通している。人間によるデバッグ や最適化などに便利である(機械による最適化には、内部表現を使ったほうが便利なので、あまり意味がない)。その意味ではアセンブリ言語は、目に見えない形ではあるが最も利用頻度の高いプログラミング言語といえるという主張もあるが、その意味では機械語が絶対的に最も利用頻度の高いプログラミング言語である。
インラインアセンブラ のある言語ないし処理系では、ソース中にアセンブリ言語による記述を含めることができる。例えばLinuxカーネル ではその利用が多い。アセンブリ言語と同様の利点が得られるかわりに、やはりアセンブリ言語と同様にプログラミング言語を使う利点(移植性など)が失われる。
脚注
注釈
^ IBMはSystem/360 から2011年現在まで一貫してアセンブラ言語 (Assembler Language)と 呼んでいる。例:IBM High Level Assembler
^ MIPSのアセンブラの一部など、(分岐命令のターゲットアドレスの先頭にある機械語命令を対象として)その分岐命令の遅延スロットへの移動を(副作用がない場合に)アセンブラ疑似命令 (.set bopt) の指示に応じて行うものもある。OPTASM(SLR社)という最適化アセンブラもあった。
^ 厳密にはCPUのビット幅に依存するが、マクロ定義はこれを条件付きコンパイルによりカバーしている。
^ GCC等、C言語への拡張によりシンボルへのセクション指定が可能なコンパイラはあるが、コンパイラへの強い依存性が生じる。アセンブリ言語であれば、およそセクションをサポートしたオブジェクトファイルが出力できるならばセクションの指定は何らかの手段で実装可能となる。
出典
^ a b "ニモニックによって表したプログラムをアセンブリ言語(assembly language)プログラムと呼ぶ。" 伊藤. 機械語とアセンブリ言語 . 埼玉大学, 電気電子物理工学実験III. 2022-12-25閲覧.
^ Stroustrup, Bjarne, The C++ Programming Language , Addison-Wesley, 1986, ISBN 0-201-12078-X : "C++ was primarily designed so that the author and his friends would not have to program in assembler, C, or various modern high-level languages." - assembler を assembly language の意味で使っている例
^ Intel Architecture Software Developer’s Manual, Volume 2: Instruction Set Reference . INTEL CORPORATION. (1999). http://download.intel.com/design/PentiumII/manuals/24319102.PDF 2010年11月18日 閲覧。
^ a b "各命令に、人間にとって意味があり、その命令が行う処理を類推できる文字列を対応付ける。この文字列をニモニック(mnemonic)と呼ぶ。" 伊藤. 機械語とアセンブリ言語 . 埼玉大学, 電気電子物理工学実験III. 2022-12-25閲覧.
^ “The SPARC Architecture Manual, Version 8 ”. SPARC, International (1992年). 2011年12月10日時点のオリジナル よりアーカイブ。2012年10月27日 閲覧。
^ a b David Salomon (1993). Assemblers and Loaders
^ Microsoft Corporation. “MASM: Directives & Pseudo-Opcodes ”. 2011年3月19日 閲覧。
^ a b c d Intel Architecture Software Developer’s Manual, Volume 2: Instruction Set Reference . INTEL CORPORATION. (1999). pp. 442 and 35. http://download.intel.com/design/PentiumII/manuals/24319102.PDF 2010年11月18日 閲覧。
^ Evans, David (2006年). “x86 Assembly Guide ”. University of Virginia. 2010年11月18日 閲覧。
^ goto
文 が存在する言語もあるが、限定利用が推奨される
^ Answers.com. “assembly language: Definition and Much More from Answers.com ”. 2008年6月19日 閲覧。
^ NESHLA: The High Level, Open Source, 6502 Assembler for the Nintendo Entertainment System
^ Z80 Op Codes for ZINT
^ コンピュータ予約システム (CRS) やクレジットカード会社で使われているトランザクションOS
^ Dr. H.D. Mills (1970) 提案、Marvin Kessler 実装 in IBM連邦政府システム部門
^ “Concept 14 Macros ”. MVS Software. 2009年5月25日 閲覧。
^ Saxon, James, and Plette, William, Programming the IBM 1401 , Prentice-Hall, 1962, LoC 62-20615. - assembly program という用語を使っている例
^ J.DONOVAN, JOHN (1972). systems programming . pp. 59. ISBN 0-07-085175-1
^ bit 編集部『bit 単語帳』共立出版 、1990年8月15日、8頁。ISBN 4-320-02526-1 。
^ Hyde, Randall. "Chapter 12 – Classes and Objects". The Art of Assembly Language, 2nd Edition. No Starch Press. © 2010.
^ (John Daintith, ed.) A Dictionary of Computing: "meta-assembler"
^ Beck, Leland L. (1996). “2”. System Software: An Introduction to Systems Programming . Addison Wesley
^ Randall Hyde. “Which Assembler is the Best? ”. 2007年10月18日時点のオリジナル よりアーカイブ。2007年10月19日 閲覧。
^ Salomon. Assemblers and Loaders . p. 7. http://www.davidsalomon.name/assem.advertis/asl.pdf 2012年1月17日 閲覧。
^ “The IBM 650 Magnetic Drum Calculator ”. 2012年1月17日 閲覧。
^ Jim Lawless (2004年5月21日). “Speaking with Don French : The Man Behind the French Silk Assembler Tools ”. 2008年8月21日時点のオリジナル よりアーカイブ。2008年7月25日 閲覧。
^ 松 --- 事実上最初のパソコン用日本語ワープロソフト
^ Toolchain, libraries and headers relationship - PlayStation Development Network
^ What were PS1 and N64 games written in? : gamedev
^ “SegaBase Volume 6 - Saturn ”. Eidolon's Inn (2008年1月10日). 2014年7月2日時点のオリジナル よりアーカイブ。2013年6月27日 閲覧。
^ Lispによるリターゲッタブルコードジェネレータの実装 (PDF) Archived 2008年8月20日, at the Wayback Machine .
^ OOエンジニアの輪! ~ 第 21 回 川合史朗 さんの巻 ~ | オブジェクトの広場
^ NVIDIA Xbox GPU Specs | TechPowerUp GPU Database
^ Using Shaders in Direct3D 10 - Win32 apps | Microsoft Docs
^ Rusling, David A.. “The Linux Kernel ”. 2012年3月11日 閲覧。
^ “Writing the Fastest Code, by Hand, for Fun: A Human Computer Keeps Speeding Up Chips ”. New York Times, John Markoff (2005年11月28日). 2010年3月4日 閲覧。
^ “Bit-field-badness ”. hardwarebug.org (2010年1月30日). 2010年2月5日時点のオリジナル よりアーカイブ。2010年3月4日 閲覧。
^ “GCC makes a mess ”. hardwarebug.org (2009年5月13日). 2010年3月16日時点のオリジナル よりアーカイブ。2010年3月4日 閲覧。
^ Randall Hyde. “The Great Debate ”. 2008年6月16日時点のオリジナル よりアーカイブ。2008年7月3日 閲覧。
^ “Code sourcery fails again ”. hardwarebug.org (2010年1月30日). 2010年4月2日時点のオリジナル よりアーカイブ。2010年3月4日 閲覧。
^ [CEDEC]「FINAL FANTASY XV」の最適化はこうして行われた - GamesIndustry.biz Japan Edition
^ “x264.git/common/x86/dct-32.asm ”. git.videolan.org (2010年9月29日). 2012年3月4日時点のオリジナル よりアーカイブ。2010年9月29日 閲覧。
^ “[https://github.com/torvalds/linux/blob/master/include/linux/export.h GitHub, torvalds /
linux, include/linux/export.h]”. 2023年10月8日 閲覧。
^ Hyde, Randall (1996年9月30日). “Foreword ("Why would anyone learn this stuff?"), op. cit. ”. 2010年3月25日時点のオリジナル よりアーカイブ。2010年3月5日 閲覧。
参考文献
Jonathan Bartlett: Programming from the Ground Up . Bartlett Publishing, 2004. ISBN 0-9752838-4-7 Also available online as PDF . 2024年3月20日閲覧。
Robert Britton: MIPS Assembly Language Programming . Prentice Hall, 2003. ISBN 0-13-142044-5
Paul Carter: PC Assembly Language . Free ebook, 2001.Website
Jeff Duntemann: Assembly Language Step-by-Step . Wiley, 2000. ISBN 0-471-37523-3
Randall Hyde: The Art of Assembly Language . No Starch Press, 2003. ISBN 1-886411-97-2
Peter Norton, John Socha, Peter Norton's Assembly Language Book for the IBM PC , Brady Books, NY: 1986.
Michael Singer, PDP-11. Assembler Language Programming and Machine Organization , John Wiley & Sons, NY: 1980.
Dominic Sweetman: See MIPS Run . Morgan Kaufmann Publishers, 1999. ISBN 1-55860-410-3
John Waldron: Introduction to RISC Assembly Language Programming . Addison Wesley, 1998. ISBN 0-201-39828-1
関連項目
外部リンク
低水準言語 高水準言語
1950年代 1960年代 1970年代 1980年代 1990年代 2000年代 2010年代
架空の言語