TepaEditorで読込むと正常に見えます。 ------------------------------------------------------- CPUとは最終的にマシン語となったプログラムの内容を解釈して実行する部品。 CPUは「レジスタ」「制御装置」「演算装置」「クロック」の4つの要素から構成されている。 レジスタ  は処理対象とする命令やデータを格納する領域です。 制御装置  はメモリー上の命令やデータをレジスタに読み出し、命令の実行結果に応じてコンピュータを制御する。 演算装置  はメモリーからレジスタに読み出されたデータを演算する役目。 クロック  はコンピュータが動作するタイミングとなるクロック信号を発生させる。 メモリーとはメインメモリー(主記憶装置)のこと。 メインメモリーは読書き可能なメモリー素子で構成されて、1バイトづつにアドレス番地が付いている。 CPUはアドレス番地を使ってメインメモリーに格納された命令やデータを取り出したり、データを書込む。 ソフトを起動するとマシン語のEXEファイルのコピーがメモリー上に作成されCPUがプログラムの内容を解釈・実行する。 CPUはプログラムが動き出すと、クロック信号に合わせて、制御装置がメモリーから命令やデータを読み出し、命令を解釈 実行するときに、演算装置でデータが演算され、その結果に応じて制御装置がコンピュータ全体を制御する。 プログラムはレジスタを使用してデータを処理している。 レジスタに格納される値は命令を表している場合と、データを表している場合がある。 データには演算に使われる値と、メモリーのアドレスを表す値の2種類がある。 ---------------------------------------------------------------------------------- アキュムレータ------------> 演算を行なうデータを格納する。 フラグ・レジスタ-----------> 演算処理後のCPUの状態を格納する。 プログラム・カウンタ------> 次に実行する命令が格納されたアドレスを格納する。 ベース・レジスタ----------> データ用のメモリー領域の先頭アドレスを格納する。 インデックス・レジスタ----> ベース・レジスタから相対アドレスを格納する。 汎用レジスタ--------------> 任意のデータを格納する。 命令レジスタ--------------> 命令そのものを格納する。 ----------------------------------------------------------------------------------- 2進数で整数を表す方法と小数点を表す方法には大きな違いがあります。 2の0乗=1 2の-1乗=0.5 2の-2乗=0.25 2の-3乗=0.125 2の-4乗=0.625 10進数の小数点数の中に、2進数に変換できないものがある。 小数点以下4桁の2進数で表される値 2進数     10進数 0 0 0.0001 0.0625 0.001 0.125 0.0011 0.1875 0.01 0.25 0.0101 0.3125 0.011 0.375 0.0111 0.4375 0.1 0.5 0.1001 0.5625 0.101 0.625 0.1011 0.6875 ---------------------------- 小数点を表すデータ型には2つある。 1、倍精度浮動小数点型 2、単精度浮動小数点型 浮動小数点数では小数点数を 符号 仮数 基数 指数 の4つの部分で表す。 ±m×n^e   ±  m  × n  e   符号 仮数   基数 指数 符号が1なら負、0なら正またはゼロを表す。 正規表現とは 10進数の浮動小数点数を「小数点以上は0とし、小数点以下の1桁目は0でない値にする」というルールを決める。 0.75=0.75*10^0 0.75=75*10^-2 0.75=0.075*10^1 ---------------- イクセス表現とは 指数部で表される最大値の1/2の値をゼロとみなすことにより、指数のための符号ビットを使わなくて済むようにする表現。 指数部8ビットである単精度浮動小数点数の場合は、最大値11111111=255の1/2である01111111=127がゼロを表す、 指数部11ビットである倍精度浮動小数点数の場合は、11111111111=2047の1/2である01111111111=1023がゼロとなる。 この127、1023の値のことをバイアスと呼ぶ。 コンピュータが計算を間違える原因の一つは、総数点数を浮動小数点数で取り扱っている。桁あふれ、桁落ちによる場合もある。 間違い回避する方法は 1、わずかな間違いなので問題にならない場合には無視する。 2、小数点数を整数に置換えて計算する。 小数点数の計算では間違えるコンピュータでも、整数の計算では間違えることはないので、計算するときに一時的に整数に して計算して、その結果を小数点数で表示する。 1部のプログラミング言語ではこの処理を自動的に行なってくれる「通貨型」というデータ型がある。 2進数はビット単位でデータを表示する場合に便利ですが、桁数が非常に多くなってしまうので判りづらい。 実際のプログラミングでは2進数のかわりに、16進数が使われる。 Visual Basic は 数値の先頭に "&H" を付けることで16進数を表せる。 C言語では 数値の先頭に "0X"を付ける事で16進数にする。 16進数とは16まで数えると桁上がりする数の数え方です。10〜15はA〜Fという記号で表されます。 16進数の1桁が、2進数の4桁に相当する。 コンピュータは、データを処理する機械であり、その処理やデータ構造を示したものがプログラムです。 処理の対象となるデータは、メモリーやディスクに格納されています。 メモリーやディスクの構造を物理的(ハードウェア的)にも論理的(ソフトウェア的)にもイメージできるようになることが必要。 メモリーICには DRAM、SRAM、ROM などがありますが、外部から見た基本的なしくみは同じです。 メモリーICには、電源、アドレス信号、データ信号、制御信号を入出力するためのピンがあり、アドレス番地を指定してデータを読書きする。 上のピンはアドレス信号ピン 10本ある。  VCC A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 ←アドレスを指定する。 +5V 0 1 0 1 0 1 0 1 0 1  ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││   ││ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││  ┌─────────────────────────────────┐ │ │ │ │ │ │ │ メモリーIC │ │ │ │ │ │ │ │ │ └─────────────────────────────────┘ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││   ││ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ 0 1 1 1 1 1 0 0 0 0 0V ←データを入力する RD WR D0 D1 D2 D3 D4 D5 D6 D7 GND ↑ 書込み信号を1にする  書込みの場合 下のピンはデータ信号ピンがD0〜D7まで8本ある。1度に8ビット(1バイト)のデータを入出力できる。 VCC、GNDは電源ピン A0〜A9はアドレス信号ピン D0〜D7はデータ信号ピン RD、WRは制御信号ピン アドレス信号ピンが10本あるので、0000000000〜1111111111の1024通りのアドレスを指定できる。 このメモリーICの中には1バイトのデータを1024個だけ格納できる。=1KBのメモリーICです。 VCC A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 ←アドレスを指定する。 +5V 0 1 0 1 0 1 0 1 0 1  ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││   ││ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││  ┌───────────────────────────────────┐ │ │ │ │ │ │ │ メモリーIC │ │ │ │ │ │ │ │ │ └───────────────────────────────────┘ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││   ││ ││ ││ ││ ││ ││ ││ ││ ││ ││ ││ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ 1 0 1 1 1 1 0 0 0 0 0V ←データを入力する RD WR D0 D1 D2 D3 D4 D5 D6 D7 GND   ↑ RD読み出し信号を1にする メモリーICにデータを書込むには 1、VCCピンに+5V、GNDピンに0Vの電源をつなぎ、データの格納場所をA0ピンからA9ピンのアドレス信号で指定し、 データの値をD0ピン〜D7ピンにデータ信号を入力し、WRピンに制御信号1を流す。 以上の動作によりメモリーICの内部にデータが書込まれる。 メモリーICのデータを読み出すには データの格納場所をA0〜A9のアドレス信号で指定し、RDピンに制御信号1を流す。 これにより指定されたアドレスに格納されているデータがD0からD7のデータ信号ピンに出力されます。 メモリーの論理的なイメージはビルディング アドレス   メモリーの内容 0000000000 1バイトのデータ ┐ 0000000001 1バイトのデータ │ 0000000010 1バイトのデータ │ | │1フロアに1バイトのデータが格納された1024階建てのビルディング(1KBのメモリー) | │ 1111111110 1バイトのデータ │ 1111111111 1バイトのデータ ┘ ----------------------------------------------------- プログラム中で変数を指定すると、WindowsなどのOSがプログラムの実行時に変数の物理的なアドレスを決定してくれるので、物理的な アドレスの指定しなくても、プログラムでメモリーの読書きが可能になる。 Windows95/98/Me/2000/XPは32ビット(4バイト)でメモリーアドレスを表しています。 C言語のポインタとは データの値そのものではなく、データが格納されているメモリーアドレスを持つ変数のことです。 通常の変数の宣言とは異なり、ポインタの宣言では変数名の前に * を付ける。 char *d; //char型のポインタdの宣言 short *e; //short型のポインタeの宣言 long *f; //long型のポインタfの宣言 ポインタの型はポインタに格納されたアドレスから一度に何バイトのデータを読書きするかを示す。 ------------------------------------------------------------ メモリーを使う基本は配列 配列とは同じデータ型(サイズ)のデータがメモリー上に並んだもの。 配列の要素となる個々のデータは、先頭から通し番号が付いている。この番号をインデックス=添字と呼ばれる。 インデックスを指定するとそれに対応するメモリー領域を読書きする。 C言語では  char g[100];   ならg[0]からg[99]の100の要素を使える。 char型なら1バイトずつ読む。 short型なら2バイトずつ読む。 long型なら4バイトずつ読む。 配列はメモリーの物理的な構造そのもの。1バイト型なら物理的メモリー構造と完全に一致する。 ループ処理の中で配列を使うと短いコードで読書きできる。 アドレス    物理メモリー   char g[100]; short h[100]; long i[100];       ┌───────┐┌───────┐┌───────┐ ┌───────┐ XXXXXX番地 │ 1バイト ││g[0]=1バイト ││    │ │ │ └───────┘└───────┘│h[0]=2バイト │ │ │       ┌───────┐┌───────┐│ │ │ │ XXXXXX番地 │ 1バイト ││g[1]=1バイト ││      │ │ │ └───────┘└───────┘└───────┘ │ i[0]=4バイト │       ┌───────┐┌───────┐┌───────┐ │ │ XXXXXX番地 │ 1バイト ││g[2]=1バイト ││      │ │ │ └───────┘└───────┘│h[1]=2バイト │ │ │         ┌───────┐┌───────┐│ │ │ │ XXXXXX番地 │ 1バイト ││g[3]=1バイト ││      │ │ │ └───────┘└───────┘└───────┘ └───────┘       ┌───────┐┌───────┐┌───────┐ ┌───────┐ XXXXXX番地 │ 1バイト ││g[4]=1バイト ││      │ │ │ └───────┘└───────┘│h[2]=2バイト │ │ │       ┌───────┐┌───────┐│ │ │ │ XXXXXX番地 │ 1バイト ││g[5]=1バイト ││      │ │ │ └───────┘└───────┘└───────┘ │ i[1]=4バイト │       ┌───────┐┌───────┐┌───────┐ │ │ XXXXXX番地 │ 1バイト ││g[6]=1バイト ││      │ │ │ └───────┘└───────┘│h[3]=2バイト │ │ │       ┌───────┐┌───────┐│ │ │ │ XXXXXX番地 │ 1バイト ││g[7]=1バイト ││      │ │ │ └───────┘└───────┘└───────┘ └───────┘ インデックスを指定して配列を使うだけではメモリーを物理的に読書きしてるだけ。 プログラムでは配列を基本にして @スタック Aキュー Bリスト C2分探索木(バイナリ・サーチ・ツリー) という配列の変形手法を使っている。 スタックとキューはどちらもアドレスやインデックスを指定しないで配列の要素を読書きできる。 スタックとキューの違いはデータの出し入れの順序の違い。 スタック-->LIFO (Last in First Out)後入れ先出し方式 キュー---->FIFO (First in First Out)先入れ先出し方式 ※読書きの順序を決めておくことでアドレスやインデックスの指定を不要としている。 スタックやキューを配列で実現するには、 1、配列を適当な要素数で宣言する。 2、配列を読書きするための関数のペアを作成する。 仮にスタックにデータを 書込む関数--->Push 読込む関数--->Pop キューからデータを 書込む関数--->Put 読込む関数--->Get //スタックへの書込み Push(123); //123が書込まれる。 Push(456); //456が書込まれる。 Push(789); //789が書込まれる。 //スタックからの読み込み j=Pop(); //789が読込まれる。 j=Pop(); //456が読込まれる。 j=Pop(); //123が読込まれる。 ------------------------------------------ //キューへの書込み Put(123); //123が書込まれる。 Put(456); //456が書込まれる。 Put(789); //789が書込まれる。 //キューへの読み込み m=Get(); //123が読込まれる。 n=Get(); //456が読込まれる。 o=Get(); //789が読込まれる。 -------------------------------------------- スタックとは「干草を積んだ山」 キューとは「待ち行列」 ============================================================================== リストと2分探索木はインデックスの順序とは無関係に配列の要素を読書きする。 リストを使うと配列にデータを追加、削除を効率的に行なえる。 2分探索木を使うと配列のデータを効率的に探索できる。 単なる配列を使った検索では配列の先頭からインデックスの順に要素を参照していかないといけない。 2分探索木は今のデータより小さければ左、大きければ右を探すのでより早く検索できる。 C言語は配列のインデックスではなく、2つのポインタを使うことで2分探索木を実現している。 ------------------------------------------------------- ディスクに記憶されたプログラムがメモリーに読込まれてから実行される。 ディスクにあるプログラムを直接実行さすことはできない。 CPUはメモリーのアドレスを指定して、そこからプログラムを読み出すようになっている。 ディスクの1部を仮想的ににメモリーとして使用する「仮想記憶」。 Windowsの仮想記憶はページング方式で、プログラムの構造に関係なくページに分割してページ単位で メモリーとディスク間の置き換えを行なう。 メモリーの内容をディスクに保存することを「ページアウト」 ディスクの内容をメモリーに読込むことを「ページイン」と呼ぶ。 ----------------------------------------------------------------- ディスクの物理構造 固定長の領域に区切る=セクター方式<-----通常はこちら 可変長の領域に区切る=パリアブル方式 ディスクの表面を同心円状に区切った領域を「トラック」、トラックを固定長に区切った領域を「セクター」 と呼ぶ。 1セクターは512バイトが普通。 ========================================== アプリケーションからOSへの命令の仕方を定めたものがAPI(アプリケーション プログラミング インターフェース) です。 BIOSとはキーボード、ディスク、グラフィック、ボードなどの制御プログラムのほか、ブート・ストラップ・ローダー という、ハードディスクに記録されたOSをメモリーにロードする役目がある。 プログラミング言語で書かれたプログラム=ソースコードという。 マシン語となったプログラム=ネイティブコード ダンプとはEXEファイルの内容を1バイトずつ16進数で表したもの。 アプリケーションソフトはOSを通して間接的にハードウェアを制御する。例)プリントアウト、ディスプレイ表示 ------------------------------------------------------------ アセンブリ言語はネイティブコードと一対一に対応する。 ネイティブコードに機能を表すニックネームを付ける--->ニックネームのことをニーモニックと呼ぶ。 ニーモニックを使うプログラミング言語をアセンブリ言語と呼ぶ。 加算を行なう---->add 比較を行なう---->cmp アセンブリ言語では1行でマイクロプロセッサに対する1つの命令を表す。 オペコード---->動詞 オペランド---->目的語 Give me money------>Giveが動詞、me moneyが目的語になる。 -------------------------------------------------------------------------------- オペコード |  オペランド | 機能 mov | A,B | AをBの値に格納する add | A,B    | Aの値とBの値を加算し、その結果をAに格納する。 push | A     | Aの値をスタックに格納する。 pop | A     | スタックから値を取り出し、それをAに格納する。 call | A     | Aという関数を呼び出す。 ret | なし    | 処理を関数の呼び出し元に戻す。 --------------------------------------------------------------------------------- レジスタとはプロセッサの中にあるメモリーのようなもの。 X86系マイクロプロセッサの持つ主なレジスタ --------------------------------------------------------------------------------- レジスタ名   呼び名                   主な機能 eax      アキュレータ             演算に使う ebx     ベース・レジスタ           メモリー・アドレスを格納する ecx     カウント・レジスタ          ループ回数をカウントする。 edx     データ・レジスタ           データを格納する。 esi     ソース・インデックス         データ転送元のメモリー・アドレスを格納する。 edi     ディスティネーション・インデックス  データ転送先のメモリー・アドレスを格納する。 ebp     ベース・ポインタ           データの格納領域のメモリー・アドレスを格納する。 esp     スタック・ポインタ          スタック領域のメモリー・アドレスを格納する。 --------------------------------------------------------------------------------- move命令のオペランドには、データの格納先と読み出し元を指定する。 値を[ ]大カッコで囲んだ場合には、値がメモリー・アドレスと解釈され、直接そのメモリー・アドレスに 読み書きされる。 mov ebp,espでは、espレジスタの値がebpレジスタに格納される。 mov eax,dword ptr[ebp+8]ではebpレジスタの値に8を加えた値がメモリーアドレスと判断される。 スタックは一時的に使われるデータが格納されるメモリー領域でpush命令とpop命令でデータの格納と読み出し を行なう。 32ビットx86系マイクロプロセッサでは1回のpush,popで32ビット(4バイト)のデータを取り扱える。