%=====================================================================
% 秋田高専 3E 電子計算機用テキスト
%    シフト命令
%      last updated 2006.2.14
%        created by  Masashi Yamamoto
%        e-mail yamamoto@akita-nct.jp
%=====================================================================
\documentclass[10pt,a4paper]{jarticle}
\usepackage{graphicx,amsmath,amssymb,ascmac,float,float}
\usepackage{html, listings, jlisting}
\oddsidemargin 0mm  %左の余白 25.4mm-0mm　奇数ページ
\evensidemargin 0mm %左の余白 25.4mm-0mm　偶数ページ
\textwidth 160mm
%
\newcommand{\tw}[1]{\texttt{#1}}
\newcommand{\vbt}[1]{\begin{verbatim} #1 \end{verbatim}}
\newcounter{linenum}
\newcommand{\wrtlinenum}{\multicolumn{1}{|r|}{\arabic{linenum}}
   \addtocounter{linenum}{1}}
%
\lstdefinelanguage{CASL2}{
morekeywords={START,END,DS,DC,OUT,RPUSH,RPOP,LD,ST,LAD,%
ADDA,SUBA,SUBL,AND,OR,XOR,CPA,CPL,SLA,SRA,SLL,SRL,%
JPL,JMI,JNZ,JZE,JOV,JUMP,PUSH,POP,CALL,RET,SVC,NOP,%
GR0,GR1,GR2,GR3,GR4,GR5,GR6,GR7},%
morecomment=[l]{;},%
morestring=[b]",%" 
}
%
\renewcommand{\lstlistingname}{リスト}
\lstset{language=CASL2,%
        basicstyle=\footnotesize,%
        commentstyle=\textit,%
        classoffset=1,%
        keywordstyle=\bfseries,%
	basewidth={0.8em,0.55em},%
	frame=tRBl,framesep=5pt,%
	showstringspaces=false,%
        numbers=left,stepnumber=1,numberstyle=\footnotesize%
}%
%
%
\begin{document}
\title{CASL IIのプログラム例(その3)}
\date{2006年2月17日}
\author{山本昌志\thanks{独立行政法人　秋田工業高等専門学校　電気工学科}}
\maketitle
%
%
%=====================================================================
\section{前回の復習と本日の学習内容}
%=====================================================================
%---------------------------------------------------------------------
\subsection{復習}
%---------------------------------------------------------------------
前回の講義では，教科書~\cite{text_casl2}の第5章の{\bf CASL IIプログラム例}の[例
題4]〜[例題7]を学習した．
\begin{itemize}
   \item {\bf [例題4]論理演算とアドレス修飾}
   \begin{itemize}\setlength\itemsep{-5pt}
    \item アドレスをずらす(オフセット)ために，アドレス修飾が使われる．アドレスと
				 汎用レジスターの\tw{GR1}〜\tw{GR7}をカンマで区
				 切れはよい．(例) \tw{LD\quad GR1,DATA,GR2}
   \end{itemize}
 \item {\bf [例題5]シフト演算}
   \begin{itemize}\setlength\itemsep{-5pt}
    \item データを左に1ビットシフトさせると2倍される．右に1ビットさせると1/2にで
				 きる．
    \item これを込み合わせて，かけ算や割り算が可能である．演算に使われる数を
				 $2^n$の和に分解するのがコツである．ただし，$n$
				 は負の数も含む．
   \end{itemize}
 \item {\bf [例題6]繰り返し処理}
   \begin{itemize}\setlength\itemsep{-5pt}
    \item ジャンプ命令とそれを制御するフラグレジスターを使って，繰り返し処理がで
				 きる．
   \end{itemize}
 \item {\bf [例題7]繰り返し処理とサブルーチン}
   \begin{itemize}\setlength\itemsep{-5pt}
    \item サブルーチンはプログラムの部品である．
    \item \tw{CALL}命令でサブルーチンを呼び出し，\tw{RET}命令で呼び出し元へ戻る．
   \end{itemize}
\end{itemize}
%
%---------------------------------------------------------------------
\subsection{本日の内容}
%---------------------------------------------------------------------
本日は教科書のp101-114の以下の内容について学習する．
\begin{itemize}
   \item {\bf [例題8]アドレスの受け渡し}
   \begin{itemize}\setlength\itemsep{-5pt}
    \item 完璧なサブルーチンを目指し，サブルーチンへのデータの渡し方を学習する．
   \end{itemize}
 \item {\bf [例題9]ラベルを2重に付ける方法}
   \begin{itemize}\setlength\itemsep{-5pt}
    \item \tw{DS}命令を使って，同じアドレスに2つのラベル名を付ける方法を学習する．
   \end{itemize}
 \item {\bf [例題10]数値データを文字データに変換}
   \begin{itemize}\setlength\itemsep{-5pt}
    \item メモリ中の整数値のデータを文字のデータとして，メモリーに格納する方法を
				 学習する．これは数値を標準出力(ディスプレイ)に
				 表示するときの必須テクニックである．
   \end{itemize}
\end{itemize}
%
%=====================================================================
\section{[例題8]アドレスの受け渡し}
%=====================================================================
%---------------------------------------------------------------------
\subsection{サブルーチンを実現するために必要なこと}
%---------------------------------------------------------------------
プログラムの規模が大きくなると，その動作の内容が分かりにくくなる．また，似たよう
な処理が増えてくる．そのため，プログラムを機能毎に分割することが行われている．機
能毎に分割した，専用のプログラムを利用するのである．このことにより
\begin{itemize}
 \item 同じような機能のプログラムは1回だけ書いて，それをプログラムのいろいろな
       場所から呼び出して何回もう．
 \item プログラムが機能毎に分かれているので，ソースが分かりやすくなる．
\end{itemize}
というようなメリットが生じる．この機能毎に分割したプログラムの単位をサブルーチン
と言う．いわゆるプログラムの部品みたいなものである．一般には，サブルーチンは簡単
な機能を持つ単純な構造にする．複雑な動作をするものが一つあるよりも，単純なものを組
み合わせて複雑な動作をさせる方が簡単である．

実際のプログラムでは，図\ref{fig:subroutine}の様な構造となる．一番左のSTARTから
ENDのラインがメインルーチンである．そして，処理Aから処理Dのラインが，それぞれサ
ブルーチンとなっている．このようにサブルーチンが集まり，プログラムができあがる．
実際の動作は，呼び出されたサブルーチンが順次動作し，プログラムが実行される．

\begin{figure}[hbtp]
 \begin{center}
  \includegraphics[keepaspectratio, scale=0.8]{figure/subroutine.eps}
  \caption{サブルーチンを使ったプログラムの構造}
  \label{fig:subroutine}
 \end{center}
\end{figure}

サブルーチンはプログラムの部品であると先程述べた．それが部品となるためには，他の
プログラムにも転用可能である必要がある．ボルトは機械要素の部品である．これは，自
動車にも使えるし，飛行機，冷蔵庫などあらゆるものに使える．自動車にしか使えないボ
ルトとなると用途が限られ，部品としては役割が小さくなる．部品として有用になるため
には，汎用性が重要となる．サブルーチンも同じで，これが有用となるためにはどのプロ
グラムでも使えるようにしなくてはならない．

このような観点から，教科書~\cite{text_casl2}の[例題7]のプログラムを見る．そのプ
ログラムはリスト\ref{prog:List_5_7}の通りで，最大値を検索サブルーチンを使ったプ
ログラムとなっている．9〜20行がサブルーチンである．このサブルーチンの部分を他の
プログラムで使おうとすると，\tw{DATA}と\tw{MAX}の部分を書き直す必要がある．プロ
グラム毎に書き直す必要があるので汎用性があるとは言い難い．あまり良いサブルーチン
とは言えない．

サブルーチンのプログラムを書き換えることなく，他のプログラムでも使えるようにしな
くてはならない．そのためには，重要なデータ，ここでは\tw{DATA}や\tw{KOSUU}，
\tw{MAX}を引数として受け渡しすればよい．実際のプログラム方法は，教科書のList5-8
で学習する．

%---------- プログラム 教科書[例題7]---------
\lstinputlisting[caption=サブルーチンを使ったプログラム例,label=prog:List_5_7]
{program/text_list_5_7e.cas}
%
%---------------------------------------------------------------------
\subsection{データの渡し方}
%---------------------------------------------------------------------
教科書のp.102にちょっと分かりにくいプログラムが載せてある．C言語が分かる人はこ
こで何が言いたいか分かるが，諸君は学習していないのであまりにも唐突に思えるだろう．
分からない人は，気にしないでも良い．

サブルーチンにデータを渡す方法は，2種類ある．{\bf アドレス渡し}と{\bf 値渡し}で
ある．図\ref{fig:data_memory}のようにメモリーにデータがあるとする．アドレス
\tw{\#0042}のデータ\tw{\#1234} をサブルーチンで処理する場合，それを渡す必要があ
る．この場合，
\begin{list}{}{%
\leftmargin=10zw \labelsep=1zw \labelwidth=10zw \itemindent=0pt
}
 \item [{\bf アドレス渡し}]処理するデータのアドレス\tw{\#0042}をサブルーチンに渡
 す．この場合，サブルーチンはアドレスを知ることが出きるので，\tw{\#0042} 番地の
 内容を書き換えることができる．
 \item[{\bf 値渡し}]処理するデータの値\tw{\#1234}をサブルーチンに渡す．この場合，
 サブルーチンはアドレスが分からないので，\tw{\#0042} 番地の内容を書き換えること
 ができない．
\end{list}
である．いずれにしても，サブルーチンは，処理すべきデータ\tw{\#1234}を知ることがで
きるが，アドレス\tw{\#0042}の内容を書き換えることができるか否かが異なる．

どちらの方法を使うかは，処理の内容により異なる．諸君が経験を積めば，どちらを使う
べきか分かるだろう．ここでは，そこまで踏み込まないことにする．

\begin{figure}[H]
 \begin{center}
  \includegraphics[keepaspectratio, scale=0.8]{figure/data_memory.eps}
  \caption{サブルーチンへ処理すべき内容を渡す方法}
  \label{fig:data_memory}
 \end{center}
\end{figure}
%
%---------------------------------------------------------------------
\subsection{教科書の例}
%---------------------------------------------------------------------
教科書の[例題8]は，[例題6]や[例題7]同様，最大値データの最大値を求めるプログラム
である．これらのプログラムで解く問題は，
\begin{itemize}
 \item ラベル\tw{DATA}が示すアドレス以降に，整数のデータが格納されている．
 \item 格納されているデータ数は，ラベル\tw{KOSUU}が示すアドレスに格納されている．
 \item 格納されている整数データの最大値を捜し，ラベル\tw{MAX}が示すアドレスに格
       納する．
\end{itemize}
である．同じ問題を解いているが，それぞれプログラムの方法が異なっており，少しずつ
プログラムが以下のように進化している．
\begin{list}{}{\leftmargin=6zw \rightmargin=3zw \labelsep=1zw%
 \labelwidth=5zw \itemindent=0pt}
 \item [{\bf [例題6]}]メインルーチンだけで最大値を求めているため，プログラムの処
      理が分かりにくいプログラムとなっている．
 \item [{\bf [例題7]}]サブルーチンを使って分かりやすいプログラムになっているが，
      サブルーチンの汎用性が無い．
 \item [{\bf [例題8]}]サブルーチンが汎用性があり，他のプログラムでも修正無しで使
      えるようになっている．
\end{list}

すでに，[例題7]までの学習は完了している．ここでは，[例題7]から[例題8]への進化の
過程を学習する．ここでの進化は，最大値を捜す関数の独立性を高め，サブルーチンを書
き換えることなく，他のプログラムに移植可能にしたことである．それを可能にするため
には，サブルーチン内では，\tw{DATA}や\tw{KOSUU}，\tw{MAX}という文字を書かないこ
とである．しかし，これらはサブルーチンでの処理上，極めて重要なデータとなっている
ので，そのデータの内容はサブルーチンに伝える必要がある．このような場合，引数を使
うのが常套手段である．教科書のList 5-8では，次節に示すように，汎用レジスターを使っ
てデータの受け渡しをしている．このようにすると，呼び出し側でレジスターに入れる変
数を変えるだけで，サブルーチンはどのようなルーチンからでも呼び出しができるように
なる．

汎用的なサブルーチンは，どんなプログラムからでも呼び出しができるようにしなくては
ならない．[例題10]のList5-10では，割り算のサブルーチンが使われており，これは頻繁
に使われるので，レジスターを使ってデータを渡している．どんな呼び出し元であれ，レ
ジスターの値を変えるだけで，サブルーチンに処理を依頼できる．
%
%---------------------------------------------------------------------
\subsection{プログラムの構造とフローチャート}
%---------------------------------------------------------------------
このプログラムのフローチャートを図\ref{fig:flow_chart_list5_8}に示す．このプログ
ラムを理解するために，ここで使われているレジスターやラベルの内容を表
\ref{tab:list9_variable}に示しておく．

汎用レジスターの\tw{GR1}と\tw{GR2}，\tw{GR3}を使って，サブルーチンで処理に必要な
データ\tw{DATA}や\tw{KOSUU}，\tw{MAX}を送っている．こうすると，他のルーチンから
もデータの先頭アドレスと個数，最大値を格納するアドレスを送れば，このサブルーチン
が処理できる．ほかのルーチンでのラベル名が異なっても，このサブルーチンが使えるの
である．

サブルーチンでは，\tw{GR1}〜\tw{GR5}を使って処理をしている．サブルーチンが終了す
るときには，メインルーチンで使っているこれらのレジスターを元に戻さなくてはならな
い．サブルーチンがメインルーチンの動作に関与する可能性が生じるからである．そのた
めに，次のような動作が必要である．
\begin{itemize}
 \item サブルーチンでは，最大値を求める処理に先立って，レジスターの値をスタック
       領域に待避させる．
 \item 最大値を求める処理が終了した後，メインルーチンに戻る前に，スタック領域に
       待避させたレジスターの値を元に戻す．
\end{itemize}
これらのことを，\tw{PUSH}と\tw{POP}命令を使って，処理している．
%
\begin{table}[H]
 \begin{center}
  \caption{汎用レジスターとメモリの内容}
  \label{tab:list6_variable}
  \begin{tabular}{lll}
   \hline
    & メインルーチン & サブルーチン \\
   \hline\hline
   DATA & データの先頭アドレス & 未使用 \\
   KOSUU & データ数が格納されたアドレス & 未使用　\\
   MAX & 最大値を格納するアドレス & 未使用 \\
   GR1 & データ数 & データ数-1 \\
   GR2 & データの先頭アドレス & 比較するデータのアドレス \\
   GR3 & 最大値を格納するアドレス & 最大値を格納するアドレス \\
   GR4 & 未使用 & カウンター(比較済みデータ数-1) \\
   GR5 & 未使用 & 比較するデータ \\
   \hline
  \end{tabular}
 \end{center}
\end{table}
%
\begin{figure}[hbtp]
 \begin{center}
  \includegraphics[keepaspectratio, scale=0.8]{flow_chart/REI5-8.eps}
  \caption{教科書のList 5-9のプログラムの構造とフローチャート}
  \label{fig:flow_chart_list5_8}
 \end{center}
\end{figure}
%
\newpage
%=====================================================================
\section{[例題9]ラベルを2重につける方法}
%=====================================================================
教科書のList5-9のプログラムを例にして，ラベルを2重につける方法について説明する．
%
%---------------------------------------------------------------------
\subsection{教科書の例}
%---------------------------------------------------------------------
教科書の[例題6](p.97)〜[例題8](p.101)は，いずれも与えられたデータの最大値を求め
るプログラムであった．これらの場合，最大値を求めたいデータの数列とその数が与えら
れていた．データ数を元に，数列を読みしと比較を繰り返すことにより最大値を探索した．
ここでは，データ数が与えられていない場合のテクニックを学習する．

教科書のプログラムの内容は，
\begin{itemize}
 \item ラベル\tw{DATA}が示すアドレスからデータが格納されている．
 \item アセンブラ命令\tw{DS}を上手に使うことにより，データの終わりのアドレスは，
       ラベル\tw{LAST-1}で示している．
 \item アドレス\tw{DATA}〜\tw{LAST-1}に格納されている数列を合計して，ラベル
       \tw{SUM}に格納する．
\end{itemize}
である．このプログラム例で学習することは，最終データがあるアドレスにラベル名をつ
けることである．それは，プログラム中で示しているように
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	DATA  DC   1,5,6,8,9    
	LAST  DS   0      ;数列の最終アドレス+1
 \end{verbatim}
\end{quote}
%
とするのである．こうすると数列の先頭のアドレスは\tw{DATA}で，最終アドレスは
\tw{LAST-1}で示すことができる．
%
%---------------------------------------------------------------------
\subsection{プログラムの構造とフローチャート}
%---------------------------------------------------------------------
このプログラムのフローチャートを図\ref{fig:flow_chart_list5_9}に示す．このプログ
ラムを理解するために，ここで使われているレジスターやラベルの内容を表
\ref{tab:list9_variable}に示しておく．プログラムの内容を理解するときには，変数が
示す内容を考えるのが第一歩である．諸君も，プログラムの内容を調べるときには，変数
の意味を調べることから始めよ．全て分からなくても良い．分かるものから，その意味を
プログラム中に書け．

このプログラムは，そんなに難しくなく，最終アドレス間で次々に加算しているのが理解
できるであろう．
%
\begin{table}[H]
 \begin{center}
  \caption{汎用レジスターとメモリの内容}
  \label{tab:list9_variable}
  \begin{tabular}{ll}
   \hline
   \tw{GR0} & 加算途中および結果の合計値 \\
   \tw{GR1} & データの最終アドレス+1(\tw{LAST})\\
   \tw{GR2} & 読み込むデータのアドレス(\tw{LAST}〜\tw{LAST-1})\\
   \tw{DATA} & 加算する数列の先頭アドレス\\
   \tw{LAST} & 加算する数列の最終アドレス\\
   \tw{SUM} & 数列を加算した結果を格納するメモリーのアドレス\\
   \hline
  \end{tabular}
 \end{center}
\end{table}
%
\begin{figure}[hbtp]
 \begin{center}
  \includegraphics[keepaspectratio, scale=0.8]{flow_chart/REI5-9.eps}
  \caption{教科書のList5-9のプログラムの構造とフローチャート}
  \label{fig:flow_chart_list5_9}
 \end{center}
\end{figure}
%
\newpage
%=====================================================================
\section{[例題10]数値データを文字データに変換}
%=====================================================================
教科書のList5-10のプログラムを例にして，数値データを文字データに変換する方法を説
明する．
%
%---------------------------------------------------------------------
\subsection{教科書の例}
%---------------------------------------------------------------------%
教科書の例のプログラムは，メモリーに格納されている整数データを文字に変換して表示
するものである．表示の約束は，以下の通りである．
%
\begin{itemize}
 \item ラベル\tw{A}に入っている数値(最大5桁)を文字列に変換して，\tw{OUT}命令で表示す
       る．
 \item 表示には6桁(カラム)用意して，第1桁は符号で負の場合のみ表示する．2〜6桁は
       絶対値を表す．ただし，上位の桁が0の場合，スペースを入れる．
\end{itemize}
%

ラベル\tw{A}の数値が最大5桁なのは，それを符号付き整数として取り扱うからである．
その場合，1ワードで表現できるのは，-32768〜32767の範囲である．これが5桁で，符号
を合わせると表示に6桁必要になる．実際には図のように，6カラムで負号のみ左端に表示
し，数値は右詰で表示する．
%
\begin{figure}[hbtp]
 \begin{center}
  \includegraphics[keepaspectratio, scale=1.0]{figure/print.eps}
  \caption{教科書のList5-10の数値を文字に変換}
  \label{fig:flow_chart_list5_A}
 \end{center}
\end{figure}
%

プログラムの作成方法と動作について，教科書に沿って説明する．
%
\begin{table}[H]
 \begin{center}
  \caption{メインルーチンの汎用レジスターとメモリの内容}
  \label{tab:list9_variable}
  \begin{tabular}{ll}
   \hline
   \tw{GR0} & 処理すべき数値(処理する毎に桁が減少) \\
   \tw{GR1} & カウンター(処理する桁を示す)\\
   \tw{GR2} & 除数\\
   \tw{GR3} & その桁の値(整数)\\
   \tw{C4} & わり算が必要な桁数\\
   \tw{BUFF} & 文字を格納するメモリーの先頭アドレス\\
   \tw{MOJI} & \tw{\#0030}．これを整数に足せば，その文字コードになる．\\
   \tw{WORK} & 以前の桁のフラグ(0:全てゼロ それ以外:ゼロ以外が現れた)\\
   \tw{WORK+1}〜\tw{4} & 桁 \\
   \hline
  \end{tabular}
 \end{center}
\end{table}
%
\begin{table}[H]
 \begin{center}
  \caption{サブルーチン\tw{DIV}の汎用レジスターとメモリの内容．このサブルーチン
  では$\tw{GR0}\div\tw{GR2}\rightarrow\text{商}\tw{GR3}\text{余り}\tw{GR0}$を計
  算している．}
  \label{tab:list9_variable}
  \begin{tabular}{lll}
   \hline
   レジスター & 実行前 & 実行後 \\
   \hline
   \tw{GR0} & 被除数 & 余り \\
   \tw{GR2} & 除数 & 除数(変化無し) \\
   \tw{GR3} & 不定 & 商 \\
   \hline
  \end{tabular}
 \end{center}
\end{table}
%
\begin{figure}[hbtp]
 \begin{center}
  \includegraphics[keepaspectratio, scale=0.7]{flow_chart/REI5-A.eps}
  \caption{教科書のList5-10のプログラムとフローチャート}
  \label{fig:flow_chart_list5_A}
 \end{center}
\end{figure}
%
%=====================================================================
%　参考文献
%=====================================================================
\bibliographystyle{jplain}
\bibliography{reference}
%=====================================================================
%
%=====================================================================
\end{document}



