1 / 18

CPU とメモリ

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

adriel
Download Presentation

CPU とメモリ

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CPUとメモリ CPU メモリ 32bit 8bit アドレス アドレスバス 演算部 0000 整数 レジスタ 0001 0002 0003 データバス ・ ・ ・ 64bit 書き込み 小数レジスタ 読み出し

  2. データの配置 int (32bit = 4byte) double (64bit = 8byte) メモリ メモリ • メモリは8bit=1byteを単位に,格納する情報の大きさに合わせて使用される • 読み書きは,各領域をひとまとめにして扱う • 左の例: • int a, b; とした場合a は 0120 - 0123 b は 0124 - 0127 • double r; とした場合r は 0120 - 0127 8bit 8bit アドレス アドレス   ・   ・ 0120 0120 0121 0121 変数a 0122 0122   ・   ・ 変数r   ・   ・   ・   ・ 変数b

  3. 配列型 8bit アドレス   ・ • 配列はメモリ中に順に確保される • 左の例: • int a[3]; として配列を定義した場合 確保される領域は全部で 12byte a[x] は 0262 + (x * 4) から始まる 4byte • double d[10] のようにした場合 確保される領域は全部で 80byte d[x] は 0262 + (x * 8) から始まる 8byte 0262 0263 a[0] 0264   ・   ・   ・ a[1] a[2]

  4. コンパイラの動作 8bit アドレス   ・ • ・メモリを 12byte 確保 (開始位置:0262) • 「0262」に 10 を入れる • 「0266+0*4」に 20 を入れる • 「0266+0*4」と「0262」の和 を計算し,その結果を 「0266+1*4」に入れる main() { int a, b[2]; a = 10; b[0] = 20; b[1] = b[0] + a;} 0262 0263 a コンパイル 0264 0265 0266   ・ b[0]   ・ ここでは,「x」は x から始まる4byteであるとする • コンパイラの動作 • 変数に必要なメモリの総量を計算する • 各変数名に実際のアドレスを対応づける • 数式を,アドレスを用いた手順に変換する b[1]

  5. メモリのアクセス 変数のアクセスに必要な情報 • 読み書きすべき変数は,どのアドレスから始まるか • 変数が格納されている大きさは,いくらか コンパイラの役目・利点 • アドレスを手計算しなくてよい • 変数の大きさの代わりに型(int, double など)を用いるので,間違いにくい.また,大きさの食い違いをチェックしてくれる

  6. ポインタの発想 8bit アドレス   ・ main() { int a, b[2]; ・・・} • コンパイラが管理する情報の利用 • 変数 a の開始位置(アドレス)を知りたい • アドレスを用いてメモリ操作したい • など 0262 0263 a 0264 0265 0266 • コンパイラが • 管理する情報 • 変数 a開始:0262大きさ:4操作単位:4 • 変数 b開始:0266大きさ:8操作単位:4   ・ b[0]   ・ 開始位置:変数名に対応 大きさ:sizeof(..) で取得可能 操作単位:型に対応 b[1]

  7. ポインタ 8bit アドレス   ・ & : 変数名からのアドレス取得&a は 0262 となる&(b[0]) は 0266 となる * : アドレスによるメモリアクセス  *(0262) で変数 a へアクセス  できるか?   →操作単位の情報が必要 main() { int a, b[2]; ・・・} 0262 0263 a 0264 0265 0266 • コンパイラが • 管理する情報 • 変数 a開始:0262大きさ:4操作単位:4 • 変数 b開始:0266大きさ:8操作単位:4   ・ b[0]   ・ b[1]

  8. ポインタ変数とポインタの型   ・ • p は int 型の   ポインタ変数 • p には int の変数の アドレスを代入する  事が出来る • *p で,p に格納され  ているアドレスから,int の大きさで アクセスできる 0262 main() { int a, b, *p; a = 10; /* 1 */ p = &a; /* 2 */ b = *p; /* 3 */ *p = 20; /* 4 */} 0263 a 0264 0265 0266   ・ b   ・ a に 10 が入る p に 262 が入る b に a の値(10)が入る a に 20 が入る p

  9. int a;int *p;p = &a; 型と文法 の解釈 p はint変数へのポインタ a はint変数 int *p; p = &a; * はポインタの前に付けると,そのポインタが指す値を意味する.つまり,int 型 & は変数の前に付けると,その型へのポインタを意味する.つまり,int 型へのポインタ 両辺は「int型」 両辺は「int型へのポインタ」 右辺と左辺の釣り合いが取れていなければならない. int 型 int 型へのポインタ a *p &a p

  10. 関数とポインタ void change(int *x) { *x = 100; } int main() { int a = 10; change(&a); } a x • a に格納された値ではなく,変数 a のポインタ(アドレス)を関数 change へ伝える事で,変数 a の内容を書き換える事が出来る(関数から値を返す事が出来る)

  11. ポインタと配列 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[0]*y y[1]*(y+1) • ポインタ変数への加算はアドレスへの加算ではなく,操作単位(型の大きさ)を乗じた値の加算となる • ポインタは配列として,また逆に配列はポインタとして使う事が出来る • a[0] と *a は等価 • a[1]と *(a+1)は等価 y

  12. ポインタの応用例 int spacecnt(char *p) { int cnt = 0; for( ; *p != ‘¥0’; p++) { if(*p == ‘ ‘) { cnt++; } } return cnt; } • 渡された文字列のスペースの個数を数えて返す関数 • p++ で,文字列の次の要素へ処理対象を移動する

  13. Malloc() と free() int *p; p = (int *)malloc(100 * sizeof(int)); *p = 100; p[99] = 200; free(p); • 必要なときに必要なだけメモリを確保する • 大きさの計算に注意(sizeof()を使う事) • 型の変換(キャスト)をきちんとするのが望ましい • 使い終わったら解放(free)する • 解放しなければどんどんメモリが浪費される

  14. 構造体 struct foo { int a; double d;};struct foo x; • x は大きさ 12byte • メンバ a は大きさ 4byte で, 開始位置は x の先頭から 0 • メンバ d は大きさ 8byte で, 開始位置は x の先頭から 4 コンパイル x.a • x の型は struct foo型 (fooはタグ名という) • x.a の型は int • x.d の型は double x x.d

  15. 構造体の利点 配列に対する利点 • 様々な型をひとまとめに出来る • 丸ごとコピーできるstruct hoge a, b; a = b; 読みやすさ,書きやすさ • 各要素に意味のある名前を付ける事が出来る • 構造体の宣言は,タグ名により再利用できる

  16. 構造体の作り方・使い方 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; 作り方(宣言と定義) • 構造体を入れることが可能 • 配列を入れることも可能 • タグ名を用いていくつでも同じ型の構造体を作る事が可能 使い方 • メンバへアクセスする演算子.は,続けて使う事が出来る

  17. 構造体へのポインタ struct st1 { int a, b;}struct st1 x;struct st1 *y;y = &x; (*y).a = 100;y->b = 200; 構造体を指すポインタが使える • 演算子*の優先順位は.や[]より低いことに注意! • 構造体へのポインタを専門に扱う演算子->が用意されているm->n は (*m).n と等価

  18. 複雑な変数定義 色を塗ってある部分が実際に確保されるメモリ int a[0] a[1] int int • 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[2] int b int int data data data p1 p1 p1 p2 p2 p2 data data p1 p1 p2 p2

More Related