18
CPU とととと CPU とととととと ととと とととと 0000 0001 0002 0003 8bit とととととと ととととと 64bit ととと とと とととと 32bit とととと とととと

CPU とメモリ

  • Upload
    adriel

  • View
    32

  • Download
    1

Embed Size (px)

DESCRIPTION

CPU とメモリ. CPU. メモリ. 32bit. 8bit. アドレス. アドレスバス. 演算部. 0000. 整数 レジスタ. 0001. 0002. 0003. データバス. ・ ・ ・. 64bit. 書き込み. 小数レジスタ. 読み出し. データの配置. int (32bit = 4byte). double (64bit = 8byte). メモリ. メモリ. メモリは 8bit=1byte を単位に,格納する情報の大きさに合わせて使用される 読み書きは,各領域をひとまとめにして扱う 左の例: - PowerPoint PPT Presentation

Citation preview

Page 1: CPU とメモリ

CPUとメモリCPU

小数レジスタ

メモリ

アドレス0000000100020003

8bit

アドレスバス

データバス64bit

演算部整数

レジスタ

32bit

書き込み

読み出し

Page 2: CPU とメモリ

データの配置

メモリ

アドレス  ・

012001210122

8bit

  ・  ・  ・

メモリ

アドレス  ・

012001210122

8bit

  ・  ・  ・

int (32bit = 4byte)

変数 b

変数 a

double (64bit = 8byte)

変数 r

•メモリは 8bit=1byteを単位に,格納する情報の大きさに合わせて使用される

•読み書きは,各領域をひとまとめにして扱う

左の例:

•int a, b; とした場合 a は 0120 - 0123 b は 0124 - 0127

•double r; とした場合 r は 0120 - 0127

Page 3: CPU とメモリ

配列型アドレス  ・

026202630264

8bit

  ・  ・  ・ a[1]

a[0]

•配列はメモリ中に順に確保される

左の例:

•int a[3]; として配列を定義した場合 確保される領域は全部で 12byte a[x] は 0262 + (x * 4) から始まる 4byte

•double d[10] のようにした場合 確保される領域は全部で 80byte d[x] は 0262 + (x * 8) から始まる 8bytea[2]

Page 4: CPU とメモリ

コンパイラの動作アドレス  ・

026202630264

8bit

02650266  ・ b[0]

a

b[1]

main() { int a, b[2];

a = 10; b[0] = 20; b[1] = b[0] + a;}

・メモリを 12byte 確保 (開始位置: 0262 )

•「 0262 」に 10 を入れる

•「 0266+0*4 」に 20 を入れる

•「 0266+0*4 」と「 0262 」の和 を計算し,その結果を 「 0266+1*4 」に入れる

  ・

コンパイル

コンパイラの動作•変数に必要なメモリの総量を計算する•各変数名に実際のアドレスを対応づける•数式を,アドレスを用いた手順に変換する

ここでは,「 x 」は x から始まる 4byte であるとする

Page 5: CPU とメモリ

メモリのアクセス

変数のアクセスに必要な情報• 読み書きすべき変数は,どのアドレスか

ら始まるか• 変数が格納されている大きさは,いくらかコンパイラの役目・利点• アドレスを手計算しなくてよい• 変数の大きさの代わりに型( int, double

など)を用いるので,間違いにくい.また,大きさの食い違いをチェックしてくれる

Page 6: CPU とメモリ

ポインタの発想アドレス  ・

026202630264

8bit

02650266  ・ b[0]

a

b[1]

main() { int a, b[2]; ・・・}

  ・

コンパイラが管理する情報•変数 a 開始: 0262 大きさ: 4 操作単位:4•変数 b 開始: 0266 大きさ: 8 操作単位:4

コンパイラが管理する情報の利用

•変数 a の開始位置(アドレス)を知りたい

•アドレスを用いてメモリ操作したい

など開始位置:変数名に対応大きさ: sizeof(..) で取得可能操作単位:型に対応

Page 7: CPU とメモリ

ポインタアドレス  ・

026202630264

8bit

02650266  ・ b[0]

a

b[1]

main() { int a, b[2]; ・・・}

  ・

コンパイラが管理する情報•変数 a 開始: 0262 大きさ: 4 操作単位:4•変数 b 開始: 0266 大きさ: 8 操作単位:4

& : 変数名からのアドレス取得  &a は 0262 となる  &(b[0]) は 0266 となる

* : アドレスによるメモリアクセス  *(0262) で変数 a へアクセス  できるか?  →操作単位の情報が必要

Page 8: CPU とメモリ

ポインタ変数とポインタの型  ・

02620263026402650266  ・ b

a

p

main() { int a, b, *p;

a = 10; /* 1 */ p = &a; /* 2 */ b = *p; /* 3 */ *p = 20; /* 4 */}  ・

1. a に 10 が入る2. p に 262 が入る3. b に a の値( 10 )が入る4. a に 20 が入る

p は int 型の   ポインタ変数•p には int の変数の アドレスを代入する  事が出来る•*p で, p に格納され  ているアドレスから,  int の大きさで アクセスできる

Page 9: CPU とメモリ

型と文法

int *p;p は int 変数へのポインタ

* はポインタの前に付けると,そのポインタが指す値を意味する.つまり, int 型

p = &a;

a は int 変数

& は変数の前に付けると,その型へのポインタを意味する.つまり, int 型へのポインタ

int 型 int 型へのポインタ

int a;int *p;

p = &a; の解釈

a*p

&ap

右辺と左辺の釣り合いが取れていなければならない.

両辺は「 int 型」 両辺は「 int 型へのポインタ」

Page 10: CPU とメモリ

関数とポインタ

x

a

void change(int *x) { *x = 100;}

int main() { int a = 10;

change(&a);}

•a に格納された値ではなく,変数 a のポインタ(アドレス)を関数 change へ伝える事で,変数 a の内容を書き換える事が出来る(関数から値を返す事が出来る)

Page 11: CPU とメモリ

ポインタと配列

a[1]*(a+1)

a[0]*a

int main() { int a[2] = {10, 20}; int *y = a;

   y[0] = 100; *(y+1) = 200; *a = 1000; *(a+1) = 2000;}

•ポインタ変数への加算はアドレスへの加算ではなく,操作単位(型の大きさ)を乗じた値の加算となる•ポインタは配列として,また逆に配列はポインタとして使う事が出来る

•a[0] と *a は等価•a[1] と *(a+1) は等価

y

y[0]*yy[1]

*(y+1)

Page 12: CPU とメモリ

ポインタの応用例

• 渡された文字列のスペースの個数を数えて返す関数

• p++ で,文字列の次の要素へ処理対象を移動する

int spacecnt(char *p) { int cnt = 0;

for( ; *p != ‘¥0’; p++) { if(*p == ‘ ‘) { cnt++; } } return cnt;}

Page 13: CPU とメモリ

Malloc() と free()

• 必要なときに必要なだけメモリを確保する–大きさの計算に注意( sizeof() を使う事)–型の変換(キャスト)をきちんとするのが望ましい

• 使い終わったら解放 (free) する–解放しなければどんどんメモリが浪費される

int *p;

p = (int *)malloc(100 * sizeof(int));*p = 100;p[99] = 200;free(p);

Page 14: CPU とメモリ

構造体

x.a

struct foo { int a; double d;};

struct foo x;

•x は大きさ 12byte

•メンバ a は大きさ 4byte で, 開始位置は x の先頭から 0

•メンバ d は大きさ 8byte で, 開始位置は x の先頭から 4

コンパイル

x.d

x •x の型は struct foo 型 ( foo はタグ名という)

•x.a の型は int

•x.d の型は double

Page 15: CPU とメモリ

構造体の利点

配列に対する利点• 様々な型をひとまとめに出来る• 丸ごとコピーできる

struct hoge a, b; a = b;

読みやすさ,書きやすさ• 各要素に意味のある名前を付ける事が出来る• 構造体の宣言は,タグ名により再利用できる

Page 16: CPU とメモリ

構造体の作り方・使い方struct st1 { int a, b;}

struct st2 { struct st1 s; double c[3];}

struct st1 x;struct st2 y;

x.a =10;y.c[0] = 10.5;y.s = x;y.s.b = 20;

作り方(宣言と定義)• 構造体を入れることが可能• 配列を入れることも可能• タグ名を用いていくつでも同

じ型の構造体を作る事が可能使い方• メンバへアクセスする演算子 .

は,続けて使う事が出来る

Page 17: CPU とメモリ

構造体へのポインタstruct st1 { int a, b;}

struct st1 x;struct st1 *y;

y = &x;

(*y).a = 100;y->b = 200;

構造体を指すポインタが使える

• 演算子 * の優先順位は . や[] より低いことに注意!

• 構造体へのポインタを専門に扱う演算子 -> が用意されているm->n は (*m).n と等価

Page 18: CPU とメモリ

複雑な変数定義• int *a[3];   int *(a[3]) と同じ

「 a は要素数 3 の配列で,その配列の各要素は int へのポインタ」

• int (*b)[3];「 b はポインタで,そのポインタが指す先は要素数 3 の配列.その配列の各要素は int 」

• struct list { int data; struct list *p1, *p2;} x;「 x は int 型の領域 data と,自分自身と同じ型の構造体を指すポインタ p をメンバに持つ構造体」

a[0]a[1]a[2]

int

intint

bintintint

datap1p2

datap1p2

datap1p2

datap1p2

datap1p2

色を塗ってある部分が実際に確保されるメモリ