ビットとは0または1の記憶の最小単位である。これが8つ並んで,1バイトとなる。
1バイト=8ビットなので,2進法で考えると00000000から11111111の値を覚えることができる。
これを10進法で表現すると0から255であり,16進法で表現すると00からFFまでである。
1バイトは16進法表現では2桁になる。
メモリは1バイト(=8ビット,16進法で表現すると2桁)のデータを多く蓄えている場所である。3.メモリの容量とアドレス
1バイトごとにアドレスが割り振られていて,0番地から1番地,2番地,・・・と続いている。
例えば,0番地に18,1番地に19,2番地に1A,3番地に1B,・・・の様にデータが保存されている様子を,
アドレスとデータのペアで表現すると,次のようになる。(データには特に意味は無い)
アドレス
データ
0
18
1
19
2
1A
3
1B
4
28
5
29
6
2A
7
2B
8
38
9
39
A
3A
B
3B
C
48
D
49
E
4A
F
4B
10
58
11
59
12
5A
13
5B
14
68
15
69
16
6A
17
6B
18
78
19
79
1A
7A
1B
7B
1C
88
1D
89
1E
8A
1F
8B
20
98
21
99
:
続く
:
上記の表現では縦に長くなりすぎるので,次のように表すのが普通で,意味するところは同じである。
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
00000
18
19
1A
1B
28
29
2A
2B
38
39
3A
3B
48
49
4A
4B
00010
58
59
5A
5B
68
69
6A
6B
78
79
7A
7B
88
89
8A
8B
00020
98
99
9A
・・・ 続く
:
続く
もし,FFF00番台のメモリ内容を32バイト分表示すると次のように表示される。
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
FFF00
18
19
1A
1B
28
29
2A
2B
38
39
3A
3B
48
49
4A
4B
FFF10
58
59
5A
5B
68
69
6A
6B
78
79
7A
7B
88
89
8A
8B
実際の表示では次のように表示することが可能である。
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
FF200 7A 07 00 0F FF 00 6B 20 00 0F F8 00 6B 21 00 0F
FF210 F8 02 09 10 6B A0 00 0F F8 04 40 FE FF F9 FF F7
メモリが16個しかない場合,アドレスは0~15(16進法表現ではF)までしかない。4ビットでアドレスを表すことができる。
もし,メモリが256個あるとすれば,アドレスは0から255(16進法表現ではFF)である。8ビットでアドレスを表すことができる。
メモリ容量と,アドレス範囲,アドレスを表すのに必要なビット数を表にまとめてみよう。
メモリ容量
アドレス範囲(16進法)
アドレスを表すのに必要なビット数
256
0~255(FF)
8
1024(=1kbytes)
0~1023(3FF)
10
65536(64kbytes)
0~65535(FFFF)
16
1048576(1Mbytes)
(1024kbytes)
0~1048575(FFFFF)
20
16777216(16Mbytes)
0~16777215(FFFFFF)
24
1073741824(1Gbytes)
(1024Mbytes)
0~1073741823(3FFFFFFF)
30
4294967296(4Gbytes)
0~4294967295(FFFFFFFF)
32
PCにおいてもメモリの表示は可能である。しかし,PCはOSがメモリアクセス(書 き込んだり読み込んだりすること)に制限をかけているので,どの番地でも自由にアクセスできるわけではない。実行中の機械語プログラムの書いてある番地 や,変数で使われている番地のメモリがアクセス可能である。
そこで,自分自身の機械語プログラムの書いてある番地のメモリを表示するプログラムは次のようになる。
配列の名前が,配列が格納されている先頭アドレスであったように,関数の名前は関数の機械語プログラムの先頭アドレスを表している。
そこで,unsigned long int 変数ptrを宣言しておくと,
ptr = (unsigned long int)main;
とすることで,関数mainの機械語プログラムの先頭アドレスを取得できる。よってつぎのような表現で,自分自身の機械語プログラムの書いてある番地のメモリを表示することができる。3つ書き方の例を示すが,どれも成功する。
自分自身の機械語プログラムの書いてある番地のメモリを表示する #include <stdio.h>
int main()
{
long int ptr;
int i,j;
ptr=(unsigned long int)main; /*mainのアドレスの取得*/
printf(" +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f\n");
for (j=0; j<0x10; j++) { /*0x10行作業する*/
printf("%08lx",ptr);
for (i=0; i<16; i++) { /*横方向に16byte表示する*/
printf(" %02x",*(unsigned char *)ptr);
ptr++;
}
printf("\n");
}
return 0;
}
#include <stdio.h>
int main()
{
long int ptr,ptr0,ptr1;
int i;
ptr0=(unsigned long int)main; /*mainのアドレスの取得*/
ptr1=ptr0+0x100; /*表示領域の最後のアドレスの設定*/
printf(" +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f\n");
for (ptr=ptr0 ; ptr<ptr1; ) {
printf("%08lx",ptr);
for (i=0; i<16; i++) {
printf(" %02x",*(unsigned char *)ptr);
ptr++;
}
printf("\n");
}
return 0;
}
#include <stdio.h>
int main()
{
long int ptr,ptr0,ptr1;
ptr0=(unsigned long int)main; /*mainのアドレスの取得*/
ptr1=ptr0+0x100; /*表示領域の最後のアドレスの設定*/
printf(" +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f\n");
for (ptr=ptr0 ; ptr<ptr1; ptr++) {
if ((ptr&0xf)==0) printf("%08lx",ptr);
printf(" %02x",*(unsigned char *)ptr);
if ((ptr&0xf)==0xf) printf("\n");
}
return 0;
}
/* 実行結果 *
このプログラムのmainは実行するたびに異なるアドレスに
配置されるため,実行するたびに異なる場所が表示される
>memdump.exe
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f
00c11000 55 8b ec 83 ec 0c c7 45 f8 00 10 c1 00 8b 45 f8
00c11010 05 00 01 00 00 89 45 f4 68 00 20 c2 00 e8 7e 00
00c11020 00 00 83 c4 04 8b 4d f8 89 4d fc eb 09 8b 55 fc
00c11030 83 c2 01 89 55 fc 8b 45 fc 3b 45 f4 7d 47 8b 4d
00c11040 fc 83 e1 0f 75 11 8b 55 fc 52 68 3c 20 c2 00 e8
00c11050 4c 00 00 00 83 c4 08 8b 45 fc 0f b6 08 51 68 44
00c11060 20 c2 00 e8 38 00 00 00 83 c4 08 8b 55 fc 83 e2
00c11070 0f 83 fa 0f 75 0d 68 4c 20 c2 00 e8 20 00 00 00
00c11080 83 c4 04 eb a8 33 c0 8b e5 5d c3 8b 0d 50 24 c2
00c11090 00 33 c0 83 c9 01 39 0d 40 31 c2 00 0f 94 c0 c3
00c110a0 6a 0c 68 f0 0d c2 00 e8 94 13 00 00 33 ff 89 7d
00c110b0 e4 33 c0 39 45 08 0f 95 c0 85 c0 75 15 e8 1f 13
00c110c0 00 00 c7 00 16 00 00 00 e8 64 03 00 00 83 c8 ff
00c110d0 eb 61 e8 2f 04 00 00 83 c0 20 50 6a 01 e8 69 04
00c110e0 00 00 59 59 89 7d fc e8 1a 04 00 00 83 c0 20 50
00c110f0 e8 1e 05 00 00 59 8b f0 8d 45 0c 50 57 ff 75 08
*/