コンピュータアーキテクチャと 機械語演習 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
© Copyright 2024