アンティーク・アセンブラ~Antique Assembler

第1回 骨董的アセンブラへの招待

この記事を読むのに必要な時間:およそ 3.5 分

昨今はモダンPerlに代表される,「より洗練されたプログラミング」を目指すムーブメントが盛り上がっています。

また,ソフトウェア開発に携わる人々の嗜好も,Web 2.0に代表されるようなサービス指向へと大きく傾いていますので,実装言語の選択においても,サービス実現という問題ドメインに適したものが望まれます。

そんなご時勢におけるアセンブラは,本連載の題名通り「骨董品」(antique)のようなものですから,わざわざ修得しようとするのは余程の物好きと言っても良いでしょう。

好事家や目利きにとっては価値があっても一般にはわかりづらいところとか,注ぎ込む手間暇の割には「役立つものがすぐに実装できる」とか「従来よりも手間暇が軽減する」などの直接的な見返りが少ない,といったところも骨董とそっくりです(骨董ファンに怒られそうですが……)。

それでは現代においてアセンブラの修得は意味がないのでしょうか?

連載の初回として,今回はアセンブラの概要について説明します。今回をお読みになって少しでも興味を引かれる点があれば,読者にとってアセンブラの修得は決して無駄にはならないでしょう。

本記事が,そんな読者のアセンブラ理解の一助になれば幸いです。

アセンブラの位置づけ

C言語におけるコンパイル処理の過程から,アセンブラの位置づけを見てみましょう

図1 コンパイル過程

図1 コンパイル過程

一般的なコンパイルの手順では,ccというコマンド(=広義のコンパイラ)が処理を受け付けて,必要とされる以下の処理を順次起動します。

1.プリプロセッサ(Pre-processor)
C言語のプログラムを入力に,マクロの展開やヘッダファイルの読み込みなどを行います(この段階で処理を止める場合のコンパイラオプションは-E)。
2.狭義のコンパイラ
プリプロセッサの結果を入力に,稼動対象環境のアーキテクチャ向けのアセンブラプログラムを生成します(この段階で処理を止める場合のコンパイラオプションは-S)。
3.アセンブラ(Assembler)
アセンブラプログラムを入力に,オブジェクトファイルを生成します(この段階で処理を止める場合のコンパイラオプションは-c)。
4.リンカ(Linker)
オブジェクトファイルを入力に,稼動対象環境における実行可能形式のファイルを生成します。

アセンブラプログラムは,稼動対象環境のCPU命令と1対1となるような記述となります(擬似命令やマクロなどがあるため,厳密には違うのですが…)。つまり,アセンブラを理解するということは,CPUに密接したレベルでソフトウェアを理解するということに他なりません。

なお,「アセンブラ(assembler)」が「アセンブリ言語(assembly language)で書かれたプログラム」「アセンブル(assemble)」する,というのが英語的には正しいのかもしれませんが,日本で「アセンブラ」と言った場合,ツールとしての「アセンブラ」を指すと同時に,「アセンブリ言語」のことも指しますので注意が必要です(本連載の表題の「アセンブラ」「アセンブリ言語」の意味で使用しています)。

「アセンブリ言語で書かれたプログラム」という名称は長いですので,本連載では「アセンブラプログラム」という呼び方をします。

アセンブラを修得すべき人

冒頭では「骨董品」と評しましたが,現代においてもアセンブラの修得が必要な状況があります。

コンパイラを開発する人

先述したように,コンパイラはコンパイル対象言語で書かれたプログラムから,対象アーキテクチャのアセンブラプログラムへの変換処理ですから,アセンブラの修得が必要です。

対象アーキテクチャは,仮想マシンのバイトコード(例:Java)や,中間言語(例:GNU Compiler Collectionの枠組みを使用する場合)だったりと,必ずしも特定の物理的なCPUに結びついたものではない場合もありますが,「アセンブラ的」な概念を理解する必要上,何らかのアーキテクチャにおけるアセンブラを1つは修得する必要があります。

オペレーティングシステム層で動作するプログラムを開発する人

オペレーティングシステム実装の大部分はC言語で書かれていますが,C言語であってもCPUの機能を100%使用できるわけではありません。

特定のCPU機能を使用するために,各CPUごとのアセンブラで記述される部位が必ず含まれますので,そういった部位の実装に関わるのであれば,アセンブラの修得が必要です。

CPU依存性のない部分(例:ファイルシステムやネットワークプロトコル)の開発をする場合,開発そのものはC言語(+カーネル内部で使用可能なAPI)の知識があれば事足りますが,実装の間違いからカーネルパニックした際にクラッシュダンプ※1の調査を行う場合などは,往々にしてアセンブラレベルの知識が必要とされます。

※1)
通常のプログラムで言うところのコアダンプに相当

ソフトウェアに対する理解を深めたい人

たとえそれがどんなに(一見)複雑そうな機能であっても,プログラムは「CPU命令の集まり」に過ぎません。

つまり,より小さい単位へと機能を分割し続けた場合,最終的にはアセンブラのレベルで底を打つわけです。

筆者は以前,「ついつい論理ゲート(AND/ORを実現する電子部品)レベルで考えてしまう」というハードウェア畑出身の開発者と会ったことがありますが,ソフトウェアのレベルで考えるなら,流石にそこまで細かく分割して理解する必要は無いでしょう。

アセンブラのレベルでソフトウェアの仕組みを考える視点を身につけることで,機能を利用する側=上位レイヤーからの見方と,機能を実現する側=下位レイヤーからの見方,という2つの方向から理解することができますので,より理解を深めることができます。

アセンブラ修得に向かない人

筆者の個人的な見解ですが,以下のような人はアセンブラ修得には向かないように思われます。

プログラミングが初めての人

1980年あたりよりも前であれば,初めてのプログラミングをアセンブラで,というのもアリ(場合によってはそれしか選択肢が無かった)でしょうが,「年寄りの体験を忠実になぞらせる」といった酔狂な理由でもなければ,21世紀にもなってソレはナシでしょう。

初心者にとっては,ある程度の抽象度を持ったプログラミング言語で,プログラミングに必要な基本的な概念を修得するのが先決です。

なお,宗教論争に巻き込まれるのを避けるため,初心者にとって最適なプログラミング言語に関しては,ここでは言及しません。

学習が暗記ベースな人

新しい分野について学習する際に,もっぱら「暗記」行為がベースになる人が少なからずいます。

開発上の必要性があるなら兎も角,ソフトウェアに関する理解の詳細化/体系化に意義を見出すのでなければ,このご時勢にアセンブラを修得するメリットは皆無,と言っても過言ではありません。

勿論,「暗記」が不要なわけでもなければ,「暗記」そのものを否定しているわけでもありません。

しかし同じ丸暗記するなら,もっと時代に即した役に立つ知識を暗記した方が,コストパフォーマンスが高いと言えます。

著者プロフィール

藤原克則(ふじわらかつのり)

Mercurial三昧の日々が嵩じて, いつの間にやら『入門Mercurial Linux/Windows対応』を上梓。凝り性なのが災いして,年がら年中アップアップな一介の実装屋。最近は仕事の縁が元で,OpenSolarisに入れ込む毎日。

コメント

  • gasについて

    > GNU Assemblerが受け付けることのできるAT&Tニーモニック

    gasは大分前からインテル文法サポートしてますよ~。

    Commented : #1  aki (2009/05/19, 19:38)

コメントの記入