コンピュータの構造と命令 コンピュータの構成要素

コンピュータの構造と命令
以降の講義の目的
高級言語(C言語,Java言語など)で書かれたプログラムを
コンピュータはどのようにして実行しているのかを理解し,
コンピュータの構造と動作を理解すること。
コンピュータの構成要素
演算データを保持
次に実行する命令
の番地を保持
プロセッサ
主記憶(1GByte)
0番地
R0
R1
R2
R3
1番地
レジスタ
プログラムカウンタ(PC)
命令,データ
2番地
命令レジスタ(IR)
命令解読器(ID)
ALU
PCの指す番地から
読み出した命令を
保持
計算を実行
命令レジスタの
内容を解読
230-1=
1073741823
番地
プログラムの命令と
データを格納
PC : Program Counter
IR : Instruction Register
ALU : Arithmetic Logical Unit
ID : Instruction Decoder
1
プロセッサの動作
z プロセッサはメモリに格納された「命令」を順番に実行していく
① ●メモリから命令を読み出してくる。
何番地から命令を読み出すか?
⇒ プロセッサ内部の「プログラムカウンタ(PC)」により指定する
次の命令の実行に備えてPCの値を増やす(インクリメントする)。
●
② 読み出した命令を解読する。
③ 命令を実行する(計算を行う)。
④ 計算結果を格納する。
コンピュータのプログラム(1)
高水準言語プログラム
(ソースプログラム)
swap(int v[ ], int k)
{int temp ;
temp=v[k] ;
v[k]=v[k+1] ;
v[k+1]=temp ;
}
機械語命令のプログラム
(オブジェクトプログラム)
0100001101001010000110
0101110010101000101110
コンパイラにより
機械語命令に
変換される
1001001000110001001011
1001001000110001001011
0101110010101000101110
0101110010101000101110
注)高水準言語:
C,Java,Basicなど
1001001000110001001011
この0と1の数字列(ビットパターン)
が主記憶に格納される
2
コンピュータのプログラム(2)
機械語命令のプログラム
(オブジェクトプログラム)
アセンブリ言語プログラム
(アセンブリプログラム)
0100001101001010000110
0101110010101000101110
1001001000110001001011
1001001000110001001011
0101110010101000101110
=
0101110010101000101110
1001001000110001001011
muli $s2,$s5,$s4
add $s2,$s4,$s2
lw $s15,0($s2)
lw $s16,4($s2)
sw $s16,0($s2)
sw $s15,4(s2)
jr $s31
この授業では,MIPS社のR2000というプロセッサ(以下ではMIPSプロセッサと
表記する)を題材にアセンブリ言語レベルでのプログラミングについて講義する。
命令の表現 : 機械語とアセンブリ言語
z 機械語(machine language)
• プロセッサが実行する命令の体系
• プロセッサの種類ごとに異なる
• 機械語は2進数あるいは16進数で表現する
1000 1101 0010 1000 0000 0100 1011 1010
0100 0101 1111 0111 1010 1110 0011 0110
z アセンブリ言語(assembly language)
• 機械語命令を記号で表現した言語
lw $t0, 1200($s0)
add $s1, $t0, $s1
sw $s1, 1200($s0)
3
8D2804BA
45F7AE36
MIPSプロセッサのイメージ
主記憶(4GByte)
プロセッサ
0番地
0
1
2
3
1番地
プログラムカウンタ(PC)
命令,データ
命令レジスタ(IR)
レジスタ
2番地
……
命令解読器(ID)
……
30
31
ALU
230-1=
1073741823
番地
主記憶(メモリ)
z データとプログラムを格納するための記憶装置
z 主記憶は「語(ワード:word) 」を単位として,プロセッサ
から読書きされる。
– 「語」は複数のbitの集まり(MIPSでは1語32bit=4byte)
z 主記憶は膨大な数の「語」からなる
– 「語」それぞれに固有の番号を付け,その番号で識別する
– その番号のことを「番地 」または「アドレス(address) 」という
– 番地はbyte単位で付けられる(0番地,1番地,2番地,…)
– 1語4byte とすると,語は4番地ごとに番地付けされる
4
MIPSの主記憶の構成
z 主記憶の各ワード(語)は,番地(アドレス)によって識別され
る。(番地はbyte単位で付けられる)
語(ワード)の番地
プロセッサからは
4の倍数の番地
で各ワードを指定
する
byte単位での番地
0番地
0番地
1番地
2番地
3番地
4番地
4番地
5番地
6番地
7番地
8番地
8番地
9番地
10番地
11番地
…………
4n番地
4n
4n+1
4n+2
4n+3
…………
1073741820番地
(230-4)
230-4
230-3
230-2
230-1
最初のワードの番地は0番地,次は4番地,次は8番地... ,となる
レジスタ(register)
• プロセッサ内部にある「データを記憶」する機構
⇒ プログラムの実行途中で,一時的な記憶に使う
• 主記憶の「語」の数に比べ,レジスタ数は非常に小さい
• プログラムにおけるレジスタの役割
– 主記憶中にあるデータをレジスタに読み込む
ロード:load 「持って来る」
– レジスタを指定して演算を行う
– 演算結果を主記憶に書き込む
ストア:store 「格納する」
5
MIPSのレジスタ
z 32個のレジスタ
– 機械語では0から31までの番号で識別される
– アセンブラ言語では名前(レジスタ名)で識別できる
z 使用目的により32個のレジスタを分類(規約)
– レジスタ $s0,$s1,$s2,……,$s7
• C言語などの高級言語でプログラム中の変数の値を保持する目的
– レジスタ $t0,$t1,$t2,……,$t7
• 演算の途中での一時的なデータを保持する目的
– レジスタ $zero
• 特別なレジスタで,常に 0 を値としてもつ
(どのような値を書き込んでも,値は0のまま → データは保存できない)
MIPSのレジスタ番号とレジスタ名
レジスタ番号
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
レジスタ名
$zero
$at
$v0
$v1
$a0
$a1
$a2
$a3
$t0
$t1
$t2
$t3
$t4
$t5
$t6
$t7
レジスタ番号
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
レジスタ名
$s0
$s1
$s2
$s3
$s4
$s5
$s6
$s7
$t8
$t9
$k0
$k1
$gp
$sp
$fp
$ra
※ アセンブリ言語では,レジスタ名で表記する
6
変数の概念
◆ 「変数」=「データの保存場所 」
保存場所はどこにあるのか?
⇒ 主記憶(メモリ)
add $t0, $s0, $s1
プログラム領域
int main( )
{
int a,b,c ;
a=1024; # ①
b=512;
#②
データ
c=a+b;
#③
(変数)領域
printf(”%d¥n”,c);
}
sub $s1, $t2, $t1
…
a
1024
①
b
512
②
c
1536
③
変数名は主記憶の
番地に対応する
変数の読書き(アクセス)
add $t0, $s0, $s1
プログラム
領域
sub $s1, $t2, $t1
…
プログラム領域とデータ領域
は一括して主記憶中に確保
される
変数領域の先頭番地(アドレス)
を保持していれば,任意の変数
にアクセスできる
データ(変数)
領域
a
1024
b
512
c
1536
$gp:global pointer
変数領域の先頭番地を保持する
$gp = 変数 a のアドレスを保持
→ 変数 b の番地 =$gp+4
変数 c の番地 =$gp+8
…
7
ロードとストアの概念
ロード(load)
• 変数の値(主記憶の語の内容)をレジスタに読み出す動作
ストア(store)
• レジスタの内容を変数に格納する(主記憶に書き込む)動作
プロセッサ
レジスタ1
主記憶
ロード(load)
-473
レジスタ2
1998
ストア(store)
a
-473
b
1998
ロード命令(load instruction)
◆ レジスタに主記憶の語の内容を読み込む動作
lw $Ri,N($Rj)
$Ri,$Rj はレジスタの一般表記
• Load Word
• レジスタ$Rjの値+N の番地の語の内容をレジスタ $Ri に
ロードする
• $Rj を「ベースレジスタ 」,Nを「オフセット 」と呼ぶ
• Nの値は16bitの2の補数表現のもとで -32768~32767
の範囲(-215~215-1)を指定できる
例1:
lw $t0, 0($t4)
例2:
lw $s0, 4($s1)
例3:
lw $t2, -128($s1)
8
オフセットの役割り
命令 lw $s0,0($t0) の動作
• レジスタ $t0 は値 10000 を保持していると仮定
• 0($t0) が表す番地: 10000+0 = 10000
• 10000
番地 の語の内容2005がレジスタ$s0 にロードされる
プロセッサ
主記憶
9996
-473
10000
2005
10004
76401
10008
-1649
10010
0
$t0 :
10000
$t1 :
42000
・・・・・・
2005
????
$s0:
・・・・・・
オフセットの役割り
命令 lw $s0,-4($t0) の動作
• レジスタ $t0 は値 10000 を保持していると仮定
• -4($t0) が表す番地: 10000-4 = 9996
• 9996
番地 の語の内容 -473 がレジスタ$s0にロードされる。
プロセッサ
主記憶
9996
-473
10000
2005
10004
76401
10008
-1649
10010
0
$t0 :
10000
$t1 :
42000
・・・・・・
$s0:
-473
2005
・・・・・・
9
ストア命令(store instruction)
◆ レジスタの値を主記憶に書き込む動作
sw $Ri,N($Rj)
$Ri,$Rj はレジスタの一般表記
• Store Word
• レジスタ$Rj の値+N の番地の語にレジスタ $Ri の
値をストアする(格納する)。
例1:
sw $t0, 0($t4)
例2:
sw $s0, -4($s1)
例3:
sw $t2, 128($s1)
オフセットの役割り
命令 sw $s0,8($t0) の動作
• レジスタ $t0 は値 10000 を保持していると仮定
• 8($t0) が表す番地: 10000+8 = 10008
• レジスタ $s0 の内容 -473 が 10008 番地の語に
ストア(格納)される
プロセッサ
主記憶
9996
-473
10000
2005
10004
76401
10008
-473
-1649
10010
$t0 :
10000
$t1 :
42000
・・・・・・
$s0:
0
-473
・・・・・・
10
変数とロード命令・ストア命令の関係
※ 変数は主記憶内の連続した領域に割り当てられる(前提)
b
変数aの番地は$gpに
格納されているとする
例:
主記憶
変数領域
※ 変数領域の先頭番地をレジスタ($gp)
に入れておき,そのレジスタにオフセットを
$gp → a
付けて変数にアクセスする
c
変数aの値を$s0レジスタにロードする
lw $s0, 0($gp)
変数bの番地=aの番地+4
=$gp+4
$s2レジスタの内容を変数cにストアする
sw $s2, 8($gp)
変数cの番地=aの番地+8
=$gp+8
…
例 変数 a と b の値を交換するプログラム
アセンブリ言語のプログラム
C言語のプログラム
w=a;
a=b;
b=w;
$gp
a
1
2
lw $t0, 0($gp)
sw $t0,8($gp)
w = a;
3
4
lw $t0, 4($gp)
sw $t0, 0($gp)
a = b;
5
6
lw $t0, 8($gp)
sw $t0, 4($gp)
b = w;
これは説明用の行番号
b
w
ある変数の値を別の変数に代入するには,
ロード命令とストア命令を使い,レジスタを
経由しなければならない
11
ロード命令・ストア命令の機械語形式
ロード命令
rs
op
offset
ベースレジスタ番号 格納先レジスタ番号
100011
31
rt
26 25
オフセット
16 15
21 20
0
ストア命令
op
rs
rt
offset
101011
ベースレジスタ番号
格納元レジスタ番号
オフセット
31
26 25
16 15
21 20
op(operation;命令) :
rs :
rt :
offset :
6bit
5bit
5bit
16bit
0
命令の種類を表す
ベースレジスタを指定する
格納先 / 格納元 レジスタを指定する
オフセットを指定する
(- 32768 ~ 32767 ; 2の補数表現)
ロード命令の機械語
レジスタ番号 レジスタ名
(アセンブリ表記)
lw $s1,100($gp)
op
100011
31
rs
rt
11100
26 25
offset
10001
21 20
$gp
(28)
0000 0000 0110 0100
16 15
100
16bitで2の補数表現
$s1
(17)
機械語の16進表記
0
8F910064
lw $t2,-100($gp)
op
rs
rt
100011
11100
01010
31
26 25
$gp
(28)
21 20
offset
1111 1111 1001 1100
16 15
$t2
(10)
機械語の16進表記
0
-100
8F8AFF9C
12
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$zero
-----------------------------------$t0
$t1
$t2
$t3
$t4
$t5
$t6
$t7
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$s0
$s1
$s2
$s3
$s4
$s5
$s6
$s7
$t8
$t9
--------$gp
----------------
ストア命令の機械語
レジスタ番号 レジスタ名
(アセンブリ表記)
sw $s1,100($gp)
op
rs
rt
101011
11100
10001
31
26 25
21 20
$gp
(28)
offset
0000 0000 0110 0100
16 15
0
100
16bitで2の補数表現
$s1
(17)
機械語の16進表記
AF910064
sw $t2,-100($gp)
op
rs
rt
101011
11100
01010
31
26 25
$gp
(28)
21 20
offset
1111 1111 1001 1100
16 15
$t2
(10)
機械語の16進表記
0
-100
AF8AFF9C
13
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$zero
-----------------------------------$t0
$t1
$t2
$t3
$t4
$t5
$t6
$t7
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$s0
$s1
$s2
$s3
$s4
$s5
$s6
$s7
$t8
$t9
--------$gp
----------------