分かりやす〜い
コンピュータ技術情報

TOPに戻る
▼Processor
簡単なアセンブラ言語
┣ 高級、低級の意味と
┃ レジスタ、mov、add

┣ 計算を行う
┣ プログラムを作る
┣ loop命令
┣ Indexレジスタの
┃ 役割とレジスタの
┃ 大きさ
┣ リピートプリフィック
┃ ス・ストリング命令

┣ inc・dec命令
┣ MMX技術
┣ MMXレジスタ
┣ MMX・SIMD・SSE
┣ CMP・JMP命令
┣ 関数とパラメータ
┣ スタック領域
┣ ESPレジスタ
┣ セグメント・
┃   call・ret

┣ コードファイルを作る
┣ コードファイル説明1
┣ コードファイル説明2
┗ マイクロコード

Copyright(C) 2001-2002.ugpop. All rights reserved.




■デジタル用語辞典:
■ コードファイル説明2 ■

前回はコードファイルの領域の「宣言」部分を説明しました。
通常、アプリケーションソフトウェアはプログラム実行コード
が格納される領域、初期化済みデータが格納される領域、未初
期化データが格納される領域など、複数の領域に分けられるこ
とを説明しました。

もう1度コードファイルを見てみましょう。
分かりやすいように意味のある部分毎に罫線で囲み、簡単な説
明を付けておきます。


─↓ここから──────────────────────

●領域の「宣言」
┌────────────────────────────┐
│_TEXT  segment dword use32 public 'CODE' ;size is 13 │
│_TEXT  ends                      │
│_DATA  segment dword use32 public 'DATA' ;size is 0 │
│_DATA  ends                      │
│CONST  segment dword use32 public 'CONST' ;size is 0 │
│CONST  ends                      │
│_BSS   segment dword use32 public 'BSS'  ;size is 0 │
│_BSS   ends                      │
└────────────────────────────┘

●領域を「1つにまとめる」指定
┌────────────────────────────┐
│FLAT  group                      │
└────────────────────────────┘

●「ライブラリ(便利な機能の集まり)」指定
┌────────────────────────────┐
│includelib SNN.lib                   │
│ extrn  __acrtused_con                │
└────────────────────────────┘

●「関数」の「宣言」
┌────────────────────────────┐
│ public  _main                    │
│ public  _sub                    │
└────────────────────────────┘

●プログラムコード領域の実体定義
┌────────────────────────────┐
│_TEXT  segment                    │
│  assume  CS:_TEXT                 │
│_main:                         │
│    push  EBX                   │
│    push  ESI                   │
│    push  EDI                   │
│    call  near ptr _sub              │
│    pop  EDI                   │
│    pop  ESI                   │
│    pop  EBX                   │
│    ret                       │
│_sub:                          │
│    ret                       │
│_TEXT  ends                      │
└────────────────────────────┘

●その他領域の実体定義
┌────────────────────────────┐
│_DATA  segment                    │
│_DATA  ends                      │
│CONST  segment                    │
│CONST  ends                      │
│_BSS   segment                    │
│_BSS   ends                      │
└────────────────────────────┘

●終了
┌────────────────────────────┐
│ end                          │
└────────────────────────────┘

─↑ここまで──────────────────────


今回は領域を「1つにまとめる」指定の説明から行ないます。


●領域を「1つにまとめる」指定
┌────────────────────────────┐
│FLAT  group                      │
└────────────────────────────┘

これはWindwosやLinux等を使用している場合に付きます。

「領域を1つにまとめる」とはどういう事でしょうか?

前回、領域を複数に分ける事の意味と必要性について説明しま
した。

折角、領域を複数に分けたのに、今度はそれを1つにまとめて
しまうという指定があるのです。

なんだか矛盾していますよね。


実はWindowsやLinuxなどのOS(オペレーティング・システム)
では、「仮想メモリ」という物が使用されています。

「仮想メモリ」とは、「あたかも大量のメモリが搭載されてい
るかの様に振舞う仕組み」の事です。

例えば、皆さんのパソコンにはメモリが何メガバイト搭載され
ているでしょうか?

大抵、128メガとか、256メガとか、多い方でも512メ
ガバイトだと思います。
例えば「512メガバイト」というのを、16進数という別の
表現方法で表すと「20000000」となります。

しかし実際にパソコンの中で使用可能なアドレスは「00000000」
〜「FFFFFFFF」までです。

「FFFFFFFF」というのは約4ギガバイトです。

つまり、メモリが最大4ギガバイトも搭載されているかのよう
に振舞えるのです。

何故、このような事が出来るのかというと、メモリだけでは足
りない部分はハードディスクを使用しているからです。

つまり、ハードディスクを「メモリの1部分であるかのように」
使用しているのです。
これが「仮想的なメモリ」の概念です。

皆さんの中にも、アプリケーションソフトを大量に動作させた
りなどしている時に、急にパソコンの動きが遅くなってしまっ
たという経験をした方がいらっしゃるのではないでしょうか?

これは「物理的な」メモリが足りなくなってしまい、ハードデ
ィスクへのアクセスが異常に多くなってしまった時に起きる現
象です。

「仮想メモリ」の詳細と動作原理について説明するとそれだけ
で1つの講座が出来上がってしまうので、これ以上の説明は省
略します。(要望が多ければ仮想メモリについての講座を開こ
うと思います。)

ここまで読んで頂いたところで、元に戻ります。


●領域を「1つにまとめる」指定
┌────────────────────────────┐
│FLAT  group                      │
└────────────────────────────┘

「領域を1つにまとめる」とはどういう事でしょうか?

仮想メモリでは、「00000000」〜「FFFFFFFF」までの、1つの
大きな領域しかありません。
ただし、これはあくまでも「仮想的な」領域です。

この仮想的な領域にアクセスするアドレス情報はプロセッサに
より自動的に「物理的な」アドレス情報へと変換されます。
この変換過程において、「仮想的な1つの」領域は「物理的な
複数の」領域に分けられます。

この事をアセンブラ言語ではたった1行で

FLAT  group

と書き、複数の領域を1つの大きな領域として扱いますよ、と
いう指定をしてあげているのです。

少し難しくなってしまいましたが、皆さんがプログラムを作成
する時には、仮想メモリについて意識する必要はありません。
全てプロセッサとOSが面倒を見てくれるからです。

普通にメモリが「00000000」〜「FFFFFFFF」までフルに使える
ものとして作成してしまいましょう。


●「ライブラリ(便利な機能の集まり)」指定
┌────────────────────────────┐
│includelib SNN.lib                   │
│ extrn  __acrtused_con                │
└────────────────────────────┘

これはDigital Mars社製コンパイラを使用した場合に限って付
いていると思います。

「includelib SNN.lib」というのは簡単に言うと「SNN.libと
いうライブラリを使用しますよ。」という意味になります。
「ライブラリ」というのは「便利な機能の集まり」の事だと思
ってください。

「extrn __acrtused_con」というのは「__acrtused_conとい
う機能を使用しますよ。」という意味になります。


●「関数」の「宣言」
┌────────────────────────────┐
│ public  _main                    │
│ public  _sub                    │
└────────────────────────────┘

これは、「このプログラムには"main"という関数と"sub"とい
う関数がありますよ」という意味になります。


●プログラムコード領域の実体定義
┌────────────────────────────┐
│_TEXT  segment                    │
│  assume  CS:_TEXT                 │
│_main:                         │
│    push  EBX                   │
│    push  ESI                   │
│    push  EDI                   │
│    call  near ptr _sub              │
│    pop  EDI                   │
│    pop  ESI                   │
│    pop  EBX                   │
│    ret                       │
│_sub:                          │
│    ret                       │
│_TEXT  ends                      │
└────────────────────────────┘

まず、最初の2行を見てみましょう。

_TEXT  segment
  assume  CS:_TEXT

これは、「ここから"TEXT"セグメント(領域)の実体の開始で
すよ。」という意味です。
「"TEXT"セグメント」というのは前回、領域の「宣言」のとこ
ろで説明しました。

もう1度「"TEXT"セグメント」の領域宣言を見てみましょう。

_TEXT  segment dword use32 public 'CODE'  ;size is 13
_TEXT  ends

この宣言は32ビットモードで動作するプログラムコードが格
納されるという「宣言」でした。

ただの「宣言」なので、「実体」の定義をする必要があるので
すが、その「実体」定義を「_TEXT  segment」の部分で行な
います。

_main:
    push  EBX
    push  ESI
    push  EDI
    call  near ptr _sub
    pop  EDI
    pop  ESI
    pop  EBX
    ret
_sub:
    ret

これが実際のmain関数とsub関数の定義です。

「call」命令と「ret」命令については既に説明しました。
「call」命令は関数を呼出す命令で、「ret」命令は関数から
復帰する命令でした。(この時、「どこに復帰するか」という
情報を格納する為に、スタック領域が使用されるという事は、
とても重要な事なので忘れないようにしましょう。)

その他の命令として、「push」命令、「pop」命令があります。
これはスタック領域にデータを格納したり、取り出したりする
命令でした。

しかし「push」命令と「pop」命令は「このプログラムでは」
全く無意味な処理です。

何故なら、この命令でスタック領域に格納されている「EBX」
「ESI」「EDI」というレジスタは「1度も使用されていない」
からです。
1度も使用されていないレジスタをわざわざスタック領域に格
納する必要はありません。

ここで示したアセンブリコードは高級言語であるC言語のコン
パイラが出力した物です。

高級言語のコンパイラが出力するコードには、時々、このよう
な無意味なコードが含まれる事があります。
(その為、実行スピードも遅くなります。)


1番最後には「_TEXT ends」というのがあります。
これは説明するまでもありませんが「TEXTセグメント実体の最
後ですよ。」という意味です。


●その他領域の実体定義
┌────────────────────────────┐
│_DATA  segment                    │
│_DATA  ends                      │
│CONST  segment                    │
│CONST  ends                      │
│_BSS   segment                    │
│_BSS   ends                      │
└────────────────────────────┘

それぞれ「データ領域」、「コンスタント領域」、「BSS領域」
の実体の開始と終了です。
このプログラムではそれぞれの領域は使用しませんので開始の
後にすぐ終了しています。


●終了
┌────────────────────────────┐
│ end                          │
└────────────────────────────┘

このファイルの終了という意味です。


非常に長くなってしまいましたが、これで一通りアセンブラ言
語について見てきた事になります。


▲このページの上へ

▲このページの上へ

←前に戻る    ▲このページの上へ    続きを読む→

▲このページの上へ

▲このページの上へ