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

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.




■デジタル用語辞典:
■ スタック領域 ■

前回は「関数」について概要を説明しました。
関数とは、ある「機能」を持った物の事でした。
また、関数が別の関数を呼出す時に、その関数にどんな処理を
して欲しいかを教えてあげる為に「パラメータ」という物を渡
す必要がある事も説明しました。

そしてそのパラメータを渡す為にはレジスタが使用されるので
すが、インテルプロセッサのレジスタ数はとても少ない為、沢
山のパラメータを渡すにはレジスタが足りないという事も説明
しました。

今回は、沢山のパラメータを渡す為には何を使用しなければな
らないのかを説明します。

前回説明したように、ある関数が別の関数を呼出す時には「パ
ラメータ」を渡してあげる必要があるのでした。

以下に、例として「アプリケーションソフトウェア」が「絵を
表示する機能」を呼出しているイメージを示します。


┌──────────────────────────┐
│      アプリケーションソフトウェア      │
│                          │
└───┬──────────────────────┘
    │                  レジスタEBX
    │ パラメータ格納         ┌──────┐
    ├────────────────→│丸い絵を表示│
    │                 └──┬───┘
    │ 呼出し ┌────────┐     │
    ├────→│絵を表示する機能│     │
    │     │        │     │
    │     └───┬────┘     │
    │         │ パラメータ参照  │
    │         │←─────────┘
    │         │
              │          画面
              │       ┌──────┐
              │ 表示    │      │
              ├───────┼→○    │
              │       │ 丸い絵  │
              │       │      │
              │       └──────┘


絵を表示する機能はこのようにして「パラメータ」を受け取る
事で「何の絵を表示しなければならないか」を知る事が出来る
のでした。

上の例ではパラメータは1つだけですが、沢山のパラメータを
渡す為には何を使用しなければならないのでしょうか?


答えは「メモリ」です。

皆さんのパソコンにも128メガバイトとか、256メガバイ
トとか、環境によりさまざまですがメモリが搭載されていると
思います。
その中の1部分を関数間でやりとりを行なう為に使用するので
す。

以下に沢山のパラメータをメモリを使用して渡しているイメー
ジを示します。


┌──────────────────────────┐
│      アプリケーションソフトウェア      │
│                          │
└───┬──────────────────────┘
    │                   メモリ
    │ パラメータ格納         ┌──────┐
    ├────────────────→│丸い絵を表示│
    │                 │  ・   │
    │ 呼出し ┌────────┐  │  ・   │
    ├────→│絵を表示する機能│  │  ・   │
    │     │        │  │  ・   │
    │     └───┬────┘  └──┬───┘
    │         │ パラメータ参照  │
    │         │←─────────┘
    │         │
              │          画面
              │       ┌──────┐
              │ 表示    │      │
              ├───────┼→○    │
              │       │ 丸い絵  │
              │       │      │
              │       └──────┘


今までパラメータをレジスタで渡していたのが、今度はメモリ
を使用して渡していますね。

メモリは128メガバイトや、256メガバイト、512メガ
バイト等、広大な領域がありますが、その中の1部分をパラメ
ータをやりとりする為に使用するのです。

そしてこの「メモリ」ですが、使われ方によっていくつかの種
類に分けられます。

例えばメモリの中でプログラムを格納する為に使用される領域
の事を「コード領域」と呼びます。また、メモリの中でデータ
を格納する為に使用される領域の事を「データ領域」と呼びま
す。

そして、パラメータを渡す為に使用される領域としては「スタ
ック領域」と呼ばれる物が使用されます。

「スタック領域」とは、その関数の中だけで使用されるデータ
や、パラメータ等、「一時的に使用される」データを格納する
為の領域の事をいいます。

「スタック領域」にデータを格納したり、取り出したりする時
は、「積み重ねるようにして」データアクセスが行なわれます。

「積み重ねるようにして」と言っても分かりにくいので下に図
を書いて説明します。


◆パラメータを入れる時

まずスタック領域に1個のパラメータを格納している図を見て
みましょう。

  パラメータ1┐
        │
        │
 スタック領域││     │
       ├│     ┤
       ││     │
       ├│     ┤
       │↓     │
       ├──────┤
       │パラメータ1│
       └──────┘


普通にパラメータが格納されただけです。
では、もう1つパラメータを格納してみましょう。


  パラメータ2┐
        │
        │
 スタック領域││     │
       ├│     ┤
       │↓     │
       ├──────┤
       │パラメータ2│
       ├──────┤
       │パラメータ1│
       └──────┘


スタック領域なので「積み重ねるようにして」パラメータが格
納されました。


◆パラメータを取り出す時

まずスタック領域から1個のパラメータを取り出している図を
見てみましょう。

          ┌→パラメータ2
          │
          │
 スタック領域│  │   │
       ├  │   ┤
       │  │   │
       ├──────┤
       │パラメータ2│
       ├──────┤
       │パラメータ1│
       └──────┘


パラメータ2の方が先に取り出されました。
では、もう1つパラメータを取り出してみましょう。


          ┌→パラメータ1
          │
          │
       │  │   │
       ├  │   ┤
       │  │   │
       ├  │   ┤
       │  │   │
       ├──────┤
       │パラメータ1│
       └──────┘


今度はパラメータ1が取り出されました。
なんとなくスタック(積み重ねる)領域の挙動がお分かり頂け
ると良いのですが。。

1番最後に格納したデータが1番最初に取り出されましたよね。
   ̄ ̄            ̄ ̄

これがスタック領域の一番の特徴です。
この入れ方/取り出し方の事をLIFO(Last In First Out)(最後
に入れたデータを最初に取り出す)と呼びます。

ちなみに、コンピュータウィルスはこの領域に書かれてある情
報を書き換えて活動する物が多いです。
スタック領域は「一時的に使用する」データを入れる為の場所
なのですが、ここに実行プログラムを入れておけば実行する事
も可能なのです。


それでは次に、スタック領域にパラメータを格納するのをアセ
ンブラ言語で書くとどうなるか、見てみましょう。


push 1

たったこれだけです。非常に簡単ですよね?
この例の場合、「1」というパラメータをスタック領域に格納
しました。


  push 1┐
        │
        │
 スタック領域││     │
       ├│     ┤
       ││     │
       ├│     ┤
       │↓     │
       ├──────┤
       │  1   │
       └──────┘


パラメータを5個スタック領域に格納したい場合は

push 1
push 2
push 3
push 4
push 5

等と書きます。
この場合、スタック(積み重ねる)領域なので、1番最後に格
納したデータがスタック領域の1番上に来ます。


 スタック領域│      │
       ├──────┤
       │  5   │
       ├──────┤
       │  4   │
       ├──────┤
       │  3   │
       ├──────┤
       │  2   │
       ├──────┤
       │  1   │
       └──────┘


では、上の様に5つのデータをスタック領域に格納後、データ
を取り出すのをアセンブラ言語で書くとどうなるか、見てみま
しょう。


pop ebx

たったこれだけです。非常に簡単ですよね?
この例の場合、スタック領域から取り出したデータはEBXレジ
スタに格納されます。


             レジスタEBX
            ┌──────┐
   pop ebx┌→│  5   │
          │ └──────┘
          │
 スタック領域│  │   │
       ├──────┤
       │  5   │
       ├──────┤
       │  4   │
       ├──────┤
       │  3   │
       ├──────┤
       │  2   │
       ├──────┤
       │  1   │
       └──────┘


続けて、もう1つデータを取り出してみましょう。
今度も同じ命令を使います。


pop ebx

この命令の動作イメージは以下の様になります。


             レジスタEBX
            ┌──────┐
   pop ebx┌→│  4   │
          │ └──────┘
          │
 スタック領域│  │   │
       ├  │   ┤
       │  │   │
       ├──────┤
       │  4   │
       ├──────┤
       │  3   │
       ├──────┤
       │  2   │
       ├──────┤
       │  1   │
       └──────┘


スタック領域なので1番最後に入れたデータから順番にデータ
が取り出されているのが分かると思います。


ここでちょっと疑問に思われた方はいらっしゃらないでしょう
か?

アセンブラコードを見てもらってお分かり頂けたかと思います
が、スタック領域からデータを取り出す時、全く同じ命令を使
用しました。


pop ebx

同じ命令なのに1番最初にスタック領域からデータを取り出す
時は、ちゃんとスタック領域の下から5番目のデータが取り出
されました。


             レジスタEBX
            ┌──────┐
   pop ebx┌→│  5   │
          │ └──────┘
          │
 スタック領域│  │   │
       ├──────┤
       │  5   │←下から5番目が取り出され
       ├──────┤ ている。
       │  4   │
       ├──────┤
       │  3   │
       ├──────┤
       │  2   │
       ├──────┤
       │  1   │
       └──────┘


             レジスタEBX
★もう1度、全く同じ命令┌──────┐
   pop ebx┌→│  4   │
          │ └──────┘
          │
 スタック領域│  │   │
       ├  │   ┤
       │  │   │
       ├──────┤
       │  4   │←今度は下から4番目が取り
       ├──────┤ 出されている。
       │  3   │
       ├──────┤
       │  2   │
       ├──────┤
       │  1   │
       └──────┘


全く同じ命令を使用したはずなのに、何故1回目と2回目とで
データが取り出される場所が異なるのでしょうか?

間違って下から5番目のデータが2度取り出されたり、また、
下から2番目や3番目のデータが取り出されたりする事はない
のでしょうか?

実は間違ってしまわないように、インテルプロセッサにはある
工夫がしてあります。

その工夫については次回説明します。



▲このページの上へ

▲このページの上へ

▲このページの上へ

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

▲このページの上へ