X86アセンブラ/基本的なFAQ
このページでは、アセンブリ言語でのプログラミング初心者の基本的なFAQについて答えよう。
目次 |
[編集] コンピュータはアセンブリ言語をどのように読んで理解するのか?
コンピュータは実際のところ読みも、理解も、何もそれ自体ではしないが、しかしこういう答えが求められている訳ではないだろう。事実は、コンピュータはあなたの書いたアセンブリ言語を読むことはできないということである。アセンブラがアセンブリ言語を機械語と呼ばれる2進数の情報の形に変換し、コンピュータはそれを使って動作するのである。コードがアセンブルされたならば、それはあなたにとって全く意味不明である。
アセンブリ言語のそれぞれの命令は、通常ただ一つの機械語に対応しているので白紙と鉛筆とアセンブリ命令のリファレンスブックだけがあれば、どんな人でもこの作業(ハンドアセンブル)を実行することができる。実際、コンピュータが使われだした最初の頃は、これは一般的にされていたことであって、基本的なコンピュータプログラムのいくつかにとっては「ハンドアセンブル」するというのは必要なことであった。このころの古典的な例としてはスティーブ・ウォズニアックによるものがある。彼は最初のApple IIコンピュータで使うために、Integer BASICインタプリタの全てを6502機械語にハンドアセンブルした。しかし、覚えておいてほしいのだが、商業的に配布されたソフトウェアのためにこのような作業がされたのは、非常にめずらしいことであるから話題になるのである。本当にほんの少しのプログラマが、実際に少数の命令についてハンドアセンブルをした経験を持っているにすぎないし、経験があるとしても学校の宿題としてやったことがあるに過ぎない。
[編集] WindowsとDOSとLinuxでアセンブリ言語は同じなのか?
この質問への答えはイエスであり、ノーでもある。基本的なx86機械語はプロセッサにのみ依存する。x86バージョンのWindowsとLinuxは明らかにx86機械語で作られている。x86アセンブリ言語でのプログラミングはオペレーティングシステム環境(LinuxとWindows)で異なっている。
- Linuxが動作している環境では、最もポピュラーなアセンブラはGASアセンブラかNASMという名前でも知られるNetWideアセンブラである。GASアセンブラでは、コードを書くためにAT&T記法が採用されており、NASMではMASMに似た記法が採用されている。
- Windowsが動作している環境では、最もポピュラーなアセンブラはMASMであり、インテル記法が採用されている。
- 使用可能なソフトウェア割り込みとその機能はWindowsとLinuxで異なっている。
- 使用可能なコードライブラリはWindowsとLinuxで異なっている。
同じアセンブラを使うならば、基本的なアセンブリコードはオペレーティングシステムによらず基本的には同じである。 しかし、Windowsと連携するならば、Linuxと連携する場合とコードは異なったものとなる。
[編集] どのアセンブラがベストか?
簡単に答えると、どのアセンブラも他のどのアセンブラよりも似たり寄ったりであり、好みや周囲の開発環境の問題である。もう少し詳しく答えると、アセンブラはそれぞれの利点と欠点がある。あなたがGAS文法しか知らないとしたら、あなたは多分GASを使いたがるであろう。インテル文法を知っておりWindowsマシンで仕事をしているのであれば、MASMを使いたくなるかもしれない。MASMやGASの癖や複雑さが好きでないならば、FASMやNASMを使いたくなるかもしれない。この本では第3節でそれぞれのアセンブラの違いを扱う。
[編集] アセンブリ言語を知る必要があるか?
ほとんどのコンピュータに関連する作業をするためにアセンブリ言語を知る必要はないが、知っておくことは良いことである。アセンブリ言語を学ぶことは、新しいプログラミング言語を学ぶということではない。新しいプログラミングプログラミングを始めようとするとき(プロジェクトがブートローダやデバイスドライバカーネルでなければ)、アセンブリ言語はやっかいものとして避けられるだろう。例外は、絶対的にパフォーマンスが重要であったり、コンパイラが最適でないコードを生成する場合である。しかし覚えておいてほしいのは、不完全な最適化は全ての悪の根源である。ただし、最適化技術が理解されており最初から計画されていれば、計算量が重要となるリアルタイムなタスクでは簡単に十分な最適化が実施できる。
しかし、アセンブリ言語を学ぶことによってコンピュータがその内部でどのように働いているのかについての部分的な見識を得ることができる。C言語、JAVA言語やAdaといった高水準言語でプログラムを書いても、コードは全て最終的には機械語の命令に変換される必要がある。そしてコンピュータによって実行される。プロセッサが何ができるかについて正確に理解することは、最も基本的なレベルにおいて、高水準言語でプログラミングをする際の助けとなる。
[編集] コードにはどのようにフォーマットを使うべきか?
ほとんどのはアセンブリコードの命令は、それぞれを各行に書き改行で分けている。また、ホワイトスペースが命令、オペランドなどを分けるのに使われる。正確に言えば、コードにどのようなフォーマットを採用すべきかは、あなたにまかされている。しかし、一般的な方法というものはいくつかある。
一つは全てを1行にする方法である。
Label1: mov ax, bx add ax, bx jmp Label3 Label2: mov ax, cx ...
もう一つは、ラベルを最初の列に書き、命令をそれ以降の列に書く方法である。
Label1: mov ax, bx
add ax, bx
jmp Label3
Label2: mov ax, cx
...
ほかにも、ラベルで1行を使い、命令を少しインデントして書く方法もある。
Label1: mov ax, bx add ax, bx jmp Label3 Label2: mov ax, cx ...
これらに加えて、ラベルを最初の列に書き、命令を以降の列に書くが、ラベルには別の行を書く方法もある。
Label1:
mov ax, bx
add ax, bx
jmp Label3
Label2:
mov ax, cx
...
本当にたくさんの書き方があるが、アセンブリプログラマが一般的に従っているルールがいくつかある。
- ラベルは、他のプログラマがどこにラベルがあるかはっきり分かるように書く。
- 構造(インデント)はコードが読みやすいようにする。
- コメントを使い、何をしているのか説明する。