第 5 回 - 情報メディア学科演習室

コンピュータアーキテクチャと
機械語演習
3年次前期 (第5回)
条件分岐命令
中島 克人
情報メディア学科
[email protected]
1
COMET Ⅱマシンの機械命令
2
COMET Ⅱマシンの機械命令
PR:Program Register
z 条件分岐命令
z
用途
無条件分岐(jump)命令
z
[書き方] JUMP adr[,xr]
[機能] e → PR
– データや演算結果により,処理を切り替える
– ループ(繰り返し)
番地eをPRにセット
=e番地に分岐
機能
– FRのいずれかのフラグの値により,オペランドで示した番地に分岐
z
z COMET Ⅱマシンの機械命令 と 分岐の条件
無条件分岐(jump)命令 … 無条件
正分岐(jump on plus)命令 … SF=0 and ZF=0
負分岐(jump on minus)命令 … SF=1
零分岐(jump on zero)命令 … ZF=1
非零分岐(jump on non zero)命令 … ZF=0
オーバフロー分岐(jump on overflow)命令 … OF=1
[書き方] JZE adr[,xr]
[機能] if ZF=1 then e → PR
この番地(通常ラベルで
指定)に分岐する
正分岐(jump on plus)命令
z
[書き方] JPL adr[,xr]
[機能] if SF=0 and ZF=0
then e → PR
z
負分岐(jump on minus)命令
[書き方] JMI adr[,xr]
[機能] if SF=1 then e → PR
3
零分岐(jump on zero)命令
非零分岐
(jump on non zero)命令
[書き方] JNZ adr[,xr]
[機能] if ZF=0 then e → PR
z
オーバフロー分岐
(jump on overflow)命令
[書き方] JOV adr[,xr]
[機能] if OF=1 then e → PR
4
アセンブリ言語CASLⅡ
z
COMET Ⅱマシンの機械命令
演習BIGR ... 素直だが上手とは言えないプログラム例
BIGR
START
LD
GR0,DAT1
z
演算か比較により
FR をセット
=<DAT2>
=<DAT1>
条件分岐命令の使い方
; <GR0> と <GR1> の大小比較
; 結果が+(プラス)ならジャンプ
FR による
条件分岐
NO
L1
DAT1
DAT2
RSLT
ST
GR0,RSLT
RET
DC 001
DC 002
DS 1
END
FR による
条件分岐
YES
条件不成立
時の処理
NO
条件不成立
時の処理
z
条件分岐命令の上手な使い方
演算か比較により
FR をセット
YES
FR による
条件分岐
NO
条件不成立
時の処理
RET
RET
条件成立時
の処理
条件成立時
の処理
共通の処理
RET
RET
5
アセンブリ言語CASLⅡ
z
演習BIGR ... CPL と JPL を使って,大きい方を求めるプログラム
を作成し,WCASL Ⅱで実行せよ
‹
なお,ラベル DAT1 には自分の学籍番号下3桁を,DAT2 には隣席学生の学
籍番号の下3桁を DC せよ
BIGR
L1
DAT1
DAT2
RSLT
START
LD
GR0,DAT1
CPL
JPL
LD
GR0,DAT2
ST
GR0,RSLT
RET
DC
DC
DS 1
END
YES
RET
6
アセンブリ言語CASLⅡ
z
演習 JZE ... 下記のプログラムのDATに自分の学籍番号を入れて
完成させ, RSLTに格納される結果を確かめよ
JZE
START
LD
GR0,DAT
; 学籍番号のロード
AND GR0,MSK1
; 最下位ビットの取り出し
JZE
EVEN
LAD GR0,#FFFF
; #FFFF → GR0
EVEN ST
GR0,RSLT
; <GR0> → RSLT
RET
DAT
DC
; 自分の学籍番号を10進数で入力
MSK1 DC
1
RSLT DS
1
END
=<DAT1>
; <GR0> と <DAT2> の大小比較
; 結果が+(プラス)ならジャンプ
; 自分の学籍番号の下3桁
; 隣席学生の学籍番号の下3桁
z
7
このプログラムJZEの機能(何をしているのか)を言葉で説明せよ
8
アセンブリ言語CASLⅡ
z
アセンブリ言語CASLⅡ
演習 JUF ... 下記のプログラムのDATに自分の学籍番号下3桁を
入れて完成させ, RSLTに格納される結果を確かめよ
z
JUF
START
LD
GR0,DAT
; 学籍番号のロード
CPL GR0,CMP1
; 50 との大小比較
JMI
UDR50
SUBA GR0,CMP1
; <GR0>-50 → GR0
CPL GR0,CMP1
; 50 との大小再比較
JMI
UDR50
SUBA GR0,CMP1
; <GR0>-50 → GR0
UDR50 ST
GR0,RSLT
; <GR0> → RSLT
RET
DAT
DC 105
; 自分の学籍番号下3桁を10進数で入力
CMP1 DC
50
RSLT DS
1
END
演習 LDST3 ... DAT~DAT+2番地の内容をADR~ADR+2番地
に格納するプログラム作成し,WCASL Ⅱで実行せよ
LDST3 START
;
;
;
;
;
;
;
;
DAT
ADR
9
DAT 番地の内容を GR0 に
<GR0> → ADR
1 → GR1
<e>(=<DAT+1>) → GR0
<GR0> → ADR+1
2 → GR1
<e>(=<DAT+2>) → GR0
<GR0> → ADR+2
RET
DC #0001,#0002,#0003 ; 定数#0001~#0003 を連続配置
DS 3
; 3語分の領域 をここに確保
END
問題:DAT~DAT+9番地の内容をADR~ADR+9番地に格納するには?
10
アセンブリ言語CASLⅡ
z
DAT~DAT+9番地の内容をADR~ADR+9番地に格納
LDST10 START
する
LDST10 START
<DAT> → GR0
<GR0> → ADR
1 → GR1
<DAT+1> → GR0
<GR0> → ADR+1
2 → GR1
<DAT+2> → GR0
<GR0> → ADR+2
:
:
:
9 → GR1
<DAT+9> → GR0
<GR0> → ADR+9
RET
0番目
1番目
2番目
9番目
0 → GR1
1 → GR2
<DAT+<GR1>> → GR0
<GR0> → ADR +<GR1>
<GR1>+<GR2> → GR1
<DAT+<GR1>> → GR0
<GR0> → ADR +<GR1>
<GR1>+<GR2> → GR1
:
:
:
<DAT+<GR1>> → GR0
<GR0> → ADR +<GR1>
(<GR1>+<GR2> → GR1)
RET
0番目
ループの構成
1番目
9番目
11
12
アセンブリ言語CASLⅡ
z
アセンブリ言語CASLⅡ
DAT~DAT+9番地の内容をADR~ADR+9番地に格納する
LDST10 START
0 → GR1
1 → GR2
<DAT+<GR1>> → GR0
<GR0> → ADR +<GR1>
<GR1>+<GR2> → GR1
<DAT+<GR1>> → GR0
<GR0> → ADR +<GR1>
<GR1>+<GR2> → GR1
:
:
:
<DAT+<GR1>> → GR0
<GR0> → ADR +<GR1>
(<GR1>+<GR2> → GR1)
RET
問題:上記の
z
LDST10 START
0 → GR1
1 → GR2
0番目
LP(ラベル)
<DAT+<GR1>> → GR0
<GR0> → ADR +<GR1>
<GR1>+<GR2> → GR1
1番目
0~9番目
if <GR1>
10
then ラベルLPまでジャンプ
9番目
DAT~DAT+9番地の内容をADR~ADR+9番地に格納する 実際
のプログラム
LDST10 START
0 → GR1
1 → GR2
LP
<DAT+<GR1>> → GR0
<GR0> → ADR +<GR1>
<GR1>+<GR2> → GR1
if <GR1>
10
then ラベルLPまでジャンプ
RET
RET
LDST10 START
LAD GR1,0
LAD GR2,1
LP
LD
GR0,DAT,GR1
ST
GR0,ADR,GR1
ADDA GR1,GR2
CPA GR1,TEN
JMI
LP
RET
TEN DC 10
DAT DC X,X,X, …, X ; 定数を10連続配置
ADR DS 10
; 10語分の領域確保
END
に入る大小記号はどれ? (a) > (b) ≧ (c) < (d) ≦
13
アセンブリ言語CASLⅡ
COMET Ⅱマシンの機械命令
z
比較(または演算)命令と条件分岐命令によるループの実現
同じ処理をn回繰り返す
z
ループカウンタ(i:ループインデックスとも)
で何回目かを制御
i = 1~n の場合
i = n~1 の場合
i=n
処理(2回目)
・・・
処理(n回目)
i回目の処理
i回目の処理
i+1→ i
i-1→ i
i≦n ?
i≧1 ?
NO
RET
RET
YES
NO
演習 STNUM ... 1,2,3~N を ADR~ ADR+(N-1)番地に格納
するプログラム作成し,WCASL Ⅱで実行せよ
(1) 繰り返し処理をまず考える
(2) ループカウンタやインデックス・レジスタを導入する
(兼用できないか検討する)
(3) ループする(同じ所に戻る)か,終了するための条件分岐法を決定する
(4) ループ回数に留意しながら,初期化部分を追加する
処理(1回目)
i=1
14
格納すべき数K(1,2,3~N) は初めに 1 にしておく(初期化)
インデックス・レジスタ i は初めに 0 にしておく(初期化)
(ループカウンタは K を兼用する)
K
→ ADR+< i >
K番目の値 → ADR+(K-1)番地
if (K>N) then 終了
K+1→ K
i +1→i
YES
RET
15
これを K=1 から K=N
まで繰り返す
16
アセンブリ言語CASLⅡ
z
アセンブリ言語CASLⅡ
演習 STNUM ... 1,2,3~N を ADR~ ADR+(N-1)番地に格納
するプログラム作成し,WCASL Ⅱで実行せよ
z
演習 STNUM ... 1,2,3~N を ADR~ ADR+(N-1)番地に格納
するプログラム作成し,WCASL Ⅱで実行せよ
STNUM START
START
LOOP
FIN
DAT
ADR
JUMP LOOP
RET
DC N
DS N
END
; 1 → GR1
; 0 → GR2 (インデックスレジスタ)
; <GR1> → ADR+<GR2>
; GR1 と Nの値の比較
; <GR1> = N ならば FIN にジャンプ
; <GR1> + 1 → GR1
; <GR2> + 1 → GR2
; LOOP に無条件ジャンプ
1→K
0→i
i回目の処理
K → ADR+<i>
YES
K=N?
NO
K+1→ K
i +1→ i
無条件分岐
; Nに適当な数を指定
; N(上記と同じ数)を指定
; 1 → GR1
; 0 → GR2 (インデックスレジスタ)
; <GR1> → ADR+<GR2>
; GR1 と Nの値の比較
; <GR1> = N ならば FIN にジャンプ
; <GR1> + 1 → GR1
; <GR2> + 1 → GR2
; LOOP に無条件ジャンプ
; Nに適当な数を指定
; N(上記と同じ数)を指定
RET
17
アセンブリ言語CASLⅡ
z
アセンブリ言語CASLⅡ
自習
演習 STNUM ... ジャンプ命令を1箇所だけに用いて,よ
り少ない行数のプログラムに書き直して見よ.
START
1→K
0→i
i回目の処理
K → ADR+<i>
K+1→ K
i +1→ i
i<N?
z
演習 SUMN ... 1,2,3~N の合計を SUM番地に格納するプログラ
ム作成せよ.なお,N は DAT番地に格納されている.
SUMN
START
DAT
SUM
DC N
DS 1
END
; 1 → GR1
; 0 → GR2 (インデックスレジスタ)
; <GR1> → ADR+<GR2>
; <GR1> + 1 → GR1
; <GR2> + 1 → GR2
; if (<GR2> < N)
; then LOOP に条件ジャンプ
YES
NO
RET
18
; Nに適当な数を指定
; N(上記と同じ数)を指定
19
; Nに適当な数を指定
; 合計の格納場所
20
アセンブリ言語CASLⅡ
z
アセンブリ言語CASLⅡ
z
演習 SUMN ... 1,2,3~N の合計を SUM番地に格納す
るプログラム作成せよ.なお,N は DAT番地に格納され
ている.
START
START
例題 MULT0 ... ラベルDAT番地の内容(mとする)をラベルN番地
の内容(nとする)倍して,ラベルRSLT番地に格納する.
MULT0
START
0→S
1→i
S+i → S
i +1→ i
YES
i,N比較
NO
LOOP
LOOP
S+i → S
i +1→ i
i≦N?
YES
YES
DAT
N
RSLT
NO
S→ SUM
S→ SUM
RET
RET
NO
‹
RET
‹
‹
21
アセンブリ言語CASLⅡ
z
LOOP
このプログラムで LOOP 番地の ADDA は何回実行されるか?
まずはプログラムを読んで予想し,次に WCASL-IIで実行して確かめよ.
カウンタ i ≧ 1 の判定の代りに JNZ,即ち i ≠ 0 の判定を行っている事に注意
DATやNを変えて,実行して見よ.
z
ループするプログラムの準備
i = 1~n の場合
; 0 → GR0 (結果の格納用レジスタを初期化)
LAD GR2,1
; カウンタ i の加算用の1
ADDA GR0,DAT ; 「処理=GR0にmを足し込む」
i=1
‹
ST
GR0,RSLT ; <GR0> → RSLT
RET
DC 100
; 被乗数 m
DC
3
; 乗数 n (ループ回数)
DS
1
END
i+1→ i
i≦n ?
NO
RET
GRx ... ループカウンタ i のためのレジスタ
GRy ... 値1の入ったレジスタ( i を+1するため)
label ... ループ処理の先頭の命令に付与
分岐方法 ... どんな演算で FR をセットし,
どの条件分岐命令でそれをテストするか?
ヒント(1) : CPL i,n ( i-n に相当)の後,
SF,ZF=0,0ならば i>n
SF,ZF=0,1ならば i=n
SF,ZF=1,0ならば i<n
i回目の処理
DAT
N
RSLT
22
COMET Ⅱマシンの機械命令
演習 MULTN ... プログラムMULT0 を 0 から n-1 まで(n はルN
番地の内容)ループするように書き換えよ.
MULTN START
LAD GR0,0
START
LAD GR0,0
; 0 → GR0 (結果の格納用レジスタを初期化)
LD
GR1,N
; n → GR1 (ループの回数を数えるカウンタ i)
LAD GR2,1
; カウンタ i の減算用の1
ADDA GR0,DAT ; 「処理=GR0にmを足し込む」
SUBA GR1,GR2 ; カウンタ i の減算 <GR1>-1→GR1
JNZ
LOOP
; カウンタ i が 0 でなければ LOOPに戻り繰り返し
ST
GR0,RSLT ; <GR0> → RSLT
RET
DC 100
; 被乗数 m
DC
3
; 乗数 n (ループ回数)
DS
1
END
YES
ヒント(2) : JZE ... ZF=1 ならば jump
JNZ ... ZF=0 ならば jump
JMI ... SF=1 ならば jump
JPL ... SF,ZF=0,0 ならば jump
JMI を使ったカウンタ i <<N> の判定の代りに JNZ,即ち i ≠<N> の判定を行って
も良い
23
24
条件分岐命令の使い分け
‹ COMET
z
Ⅱが備える条件分岐命令の分岐条件
JPL(jump on plus)
直前の演算結果 > 0
直前の比較 <gr1> > <gr2>|<e>
z
直前の演算結果 < 0
直前の比較 <gr1> < <gr2>|<e>
z
JZE(jump on zero)
直前の演算結果 = 0
直前の比較 <gr1> = <gr2>|<e>
z
1→i
0→i
i回目の処理
i回目の処理
i+1→ i
i+1→ i
JMI(jump on minus)
JNZ(jump on non zero)
直前の演算結果 ≠ 0
直前の比較 <gr1> ≠ <gr2>|<e>
i≦n ?
i<n ?
YES
NO
YES
NO
RET
RET
‹ 実現したいアルゴリズムで
≦ や ≧ がある時,ループカウンタ値
をずらして < や > に置き換えられることもある.
可能なら,ループカウンタ値の増減を逆に使用しても良い.
25