%=====================================================================
% 秋田高専 3E 電子計算機用テキスト
%    シフト命令
%      last updated 2006.2.2
%        created by  Masashi Yamamoto
%        e-mail yamamoto@akita-nct.jp
%=====================================================================
\documentclass[10pt,a4paper]{jarticle}
\usepackage{graphicx,amsmath,amssymb,ascmac,float,float}
\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}}
%
\newcounter{toi_num}
\newcommand{\toi}{\textbf{\texttt [問\arabic{toi_num}]}
   \addtocounter{toi_num}{1}}
%
\begin{document}
\title{CASL IIのプログラム例(その1)}
\date{2006年2月2日}
\author{山本昌志\thanks{国立秋田工業高等専門学校　電気工学科}}
\maketitle
%
%=====================================================================
\section{今後の学習}
%=====================================================================
今後は，CASL IIを通して，アセンブラーのプログラムの書き方を学習する．教科書~
\cite{text_casl2}に沿って進めるが，ある人にとっては簡単すぎるであろう．また，基
本情報技術者試験を受ける人にとっては，内容は不足している．そのため，この程度の内
容が理解できる人は，講義とは別に勝手に進んで欲しい．
%
%=====================================================================
\section{プログラムの見方}
%=====================================================================
以前述べたように，プログラムは命令とデータから構成される．高級言語の場合，プログ
ラムの大部分は命令である．データは外部のファイルから呼び出すことが多いので，ソー
スプログラムには書かれないことが多い．というか，あちこちに書いて，どうなっている
のか分からないことも多い．それに対して，機械語やアセンブラのソースプログラムでは，
命令部とデータ部を明確にするのが良い．

アセンブラのプログラムを見る場合，まず最初に，どの部分が命令で，どの部分がデータ
かを見分けなくてはならない．また，命令部はメインルーチンとサブルーチンをも見分け
なくてはならない．これらを，見分けるのは簡単である．慣れればすぐにわかるが，大体
の目安は，以下のとおりである．
%
\begin{itemize}
\item メインルーチンは，\tw{START}命令で指定されたアドレスから\tw{RET}命令までである．
\item サブルーチンは，メインルーチン同様\tw{RET}命令で終わっている．始まりは
      \tw{START}命令が有ったり無かったりであるが，必ずラベルはある．メインルーチ
      ンと異なるのは，それがメインルーチンあるいは他のサブルーチンから\tw{CALL}命令
      で呼び出されていることである．実際のところ，メインルーチンもOSから
      \tw{CALL}命令で呼び出されているため，諸君が書くプログラムには無いのである．
      ハードウェアーにとっては，メインルーチンもサブルーチンも区別していないので
      ある．
\item データ部は，\tw{DC}あるいは\tw{DS}命令が書かれている行である．
\end{itemize}

プログラムを構成するこれらの3つの要素は，それぞれ一塊にかかれるのが普通である．
一塊に書かないようにもできるが，それは非常にわかりにくいプログラムとなり，絶対に
避けるべきである．少しでも経験のあるプログラマーならば，これらの要素は区別して分
かりやすく書いている．センスのない人ほど，複雑でわかりにくいプログラムを書く．

\begin{screen}
ソースプログラムを見たり書いたりする場合，メインルーチンとサブルーチン，データ部
 に分ることから始めよ．
\end{screen}
%
%=====================================================================
\section{[例題1]加算}
%=====================================================================
教科書~\cite{text_casl2}のList5-1のプログラムを例にして，加算方法について説明する．
%---------------------------------------------------------------------
\subsection{高級言語との違い}
%---------------------------------------------------------------------
高級言語の場合，加算は，
%
 \begin{quote}
  \setlength{\baselineskip}{12pt}
  \begin{verbatim}	
	wa=a+b;
  \end{verbatim}
 \end{quote}
%
%
のように書けばよい．数式と同じように書けば，\tw{a+b}を実行し，その結果を変数\tw{wa}に
格納する．

しかし，アセンブラーでは，こんなに簡単ではない．加算はCPUで行うが，そのためのデー
タはCPUが持っているメモリーであるレジスターを使って計算を行う．そのため，次のよ
うな手順が必要である．
\begin{enumerate}
 \item 計算の対象のデータを，メモリーから，レジスターにロードする．
 \item 計算を行う．計算結果は，レジスターに蓄えられる．
 \item レジスターに蓄えられた計算結果をメモリーにストアーする．
\end{enumerate}

全ての計算は，レジスターを通して行われるので，このような手間が必要なのである．こ
れは，コンピューターのハードウェアーがそうなっているからである．アセンブラー言語
は，コンピューターのハードウェアーを反映しているのである．アセンブラー言語でプロ
グラムをする場合，ハードウェアーの思い浮かべれば，高級言語との違いが明確になる．

実際，高級言語ではコンパイラー\footnote{高級言語のソースプログラムを機械語に変換
するプログラム}が，レジスターの処理とかの機械語のプログラムに直している．これは，
同じハードウェアーで計算するので，やはり，高級言語と言えども最終的にはレジスター
を使っているのである．
%
%---------------------------------------------------------------------
\subsection{プログラムの構造}
%---------------------------------------------------------------------
まず，リストを見て，プログラムが図\ref{fig:structure_list5_2}の構造になっているこ
とを理解しなくてはならない．プログラムは，訳の分からない呪文が連なっているのでは
なく，ちゃんと整理すれば理解できる．まずは，これが第一歩である．
%
\begin{figure}[H]
 \begin{center}
  \includegraphics[keepaspectratio, scale=1.0]{figure/REI5-1.eps}
  \caption{教科書のList5-1のプログラムの構造．}
  \label{fig:structure_list5_1}
 \end{center}
\end{figure}
%
%---------------------------------------------------------------------
\subsection{フローチャート}
%---------------------------------------------------------------------
このプログラムのフローチャートを図\ref{fig:flow_chart_list5_1}に示す．このプログ
ラムは簡単で，水が上から下に流れるように命令部が順番に実行されるだけである．この
ように，書かれた順にプログラムが実行される構造を「順次」と言う．
%
\begin{figure}[H]
 \begin{center}
  \includegraphics[keepaspectratio, scale=1.0]{flow_chart/REI5-1.eps}
  \caption{教科書のList5-1のプログラムのフローチャート．}
  \label{fig:flow_chart_list5_1}
 \end{center}
\end{figure}
%
%=====================================================================
\section{[例題2]加算と条件分岐}
%=====================================================================
教科書のList5-2のプログラムを例にして，条件分岐について説明する．
%---------------------------------------------------------------------
\subsection{高級言語との違い}
%---------------------------------------------------------------------
高級言語の場合，条件分岐は簡単に実装できる．例えば，変数\tw{a}と\tw{b}の大きい方
から小さい方を減算する場合，
%
 \begin{quote}
  \setlength{\baselineskip}{12pt}
  \begin{verbatim}	
	if(a<b){
	  c=b-a;
	}else{
	  c=a-b;
	}
  \end{verbatim}
 \end{quote}
%
%
と書けばよい．ここで，\tw{if}文の括弧の中の演算を制御式と言う．高級言語は，人間
が使っている言葉とほとんど同じで，プログラムが簡単に書ける．

しかし，アセンブラーでは，こんなに簡単ではない．そもそも，\tw{if}文がないため，
それに変わるテクニックを使わなくてはならない．機械語命令を組み合わせて，高級言語
の\tw{if}文と同じことをするのである．かなりプログラムは面倒であるが，その分コン
ピューターのハードウェアー(特にCPU)は簡単になり，高速の動作が可能になる．

アセンブラー言語で\tw{if}のような制御文を実現するためには，次のようにする．
\begin{enumerate}
 \item 制御式の結果をフラグレジスターに設定する．通常\tw{CPA}や\tw{CPL}命令が使
       われるが，フラグレジスターが設定できるもので有れば何でも良い．
 \item フラグレジスターの値により，分岐する命令(\tw{JMI, JNZ, JZE, JUMP, JPL,
       JOV})を使い，実行する文を選択する．
 \item ジャンプ先は，ラベルで指定する．
\end{enumerate}
%
%---------------------------------------------------------------------
\subsection{プログラムの構造}
%---------------------------------------------------------------------
まず，リストをみて，プログラムが図\ref{fig:structure_list5_2}の構造になっている
ことを理解しなくてはならない．
%
\begin{figure}[H]
 \begin{center}
  \includegraphics[keepaspectratio, scale=1.0]{figure/REI5-2.eps}
  \caption{教科書のList5-2のプログラムの構造．}
  \label{fig:structure_list5_2}
 \end{center}
\end{figure}
%
%---------------------------------------------------------------------
\subsection{フローチャート}
%---------------------------------------------------------------------
このプログラムのフローチャートを図\ref{fig:flow_chart_list5_2}を示す．このプログ
ラムは，[例題1]とは異なり，プログラムの実行が条件に従い分岐する．このようなプロ
グラムの構造を「選択」という．ここでは，この選択がフラグレジスターの値を制御値と
してジャンプ命令で実装されていることを理解しなくてはならない．

それから，出力命令\tw{OUT}も理解しなくてはならない．
\begin{itemize}
 \item \tw{OUT}命令の最初のオペランドは，出力したい文字が格納されている先頭アドレスで
 ある．
 \item 2番目のオペランドは，出力する文字数が格納されているアドレスである．これが
       ないと，何文字出力するか，コンピューターは分からない．
\end{itemize}
%
\begin{figure}[H]
 \begin{center}
  \includegraphics[keepaspectratio, scale=1.0]{flow_chart/REI5-2.eps}
  \caption{教科書のList5-2のプログラムのフローチャート．}
  \label{fig:flow_chart_list5_2}
 \end{center}
\end{figure}
%
%=====================================================================
\section{[例題3]マスク処理と条件分岐}
%=====================================================================
教科書のList5-3のプログラムを例にして，マスク処理と条件分岐について説明する．
%
%---------------------------------------------------------------------
\subsection{マスク処理}
%---------------------------------------------------------------------
%------------------------
\subsubsection{教科書の例}
%------------------------
データの特定のビットパターンを選び出すことをマスキングという．このビットパターン
を選び出すために，演算を行うわけであるが，その演算のためのデータをマスクと言う．
例えば，教科書のList5-3の場合，2行目の\tw{AND GR0,MASK}がマスキング(マスク処理)
であって，ラベル\tw{A}のデータがマスクである．このマスクを用いたマスキングにより，
\tw{GR0}特定のビットパターンを選び出している．

ここでは，次のようにしている．$(1452)_{10}=(0000010110101100)_2$なので
%
\begin{equation}
 \begin{array}{ll}
          & \tw{0000010110101100} \\
 \tw{AND} & \tw{0000000000000001} \\ \hline
          & \tw{0000000000000000}
 \end{array}
 \nonumber
\end{equation}
%
としている．仮に，ラベル\tw{A}の値が$(1453)_3$としたら，
%
\begin{equation}
 \begin{array}{ll}
          & \tw{0000010110101101} \\
 \tw{AND} & \tw{0000000000000001} \\ \hline
          & \tw{0000000000000001}
 \end{array}
 \nonumber
\end{equation}
%
となる．この例から分かるように，論理積(\tw{AND})の結果は，ラベル\tw{A}の最下位ビッ
トに依存していることが分かる．最下位ビットの1の有無は，フラグレジスタの\tw{ZF}を
見れば分かる．演算の結果，全てのビットがゼロになれば，\tw{ZF=1}となる．

データの調べたいビットは，マスクにより指定している．このように，調べたいビットを
しているデータマスクという．要するに，お面(マスク)で顔の一部を隠すように，興味の
ないビットを隠しているのである．
%
%---------------------------------------------
\subsubsection{特定のビットパターンのマスクの方法}
%---------------------------------------------
先の例でも分かるが，\tw{AND}を使ったマスク処理の場合，マスクは興味の対象のビット
を1，どうでも良いビットを0にする．そうすると，興味のないビットは全てゼロとなり，
重要なビットは変更されない．先の場合，ある特定の1ビットの状態が分かれば良かった
ので，マスク処理後，直ぐにフラグレジスタ\tw{ZF}を見た．もう少し複雑な場合は，こ
れではだめである．特定のビットパターンを調べたい場合である．例えば，
%
\begin{align}
 \tw{$\ast\ast\ast\ast$1010$\ast\ast\ast\ast$1100}
 \nonumber
\end{align}
%
のような場合である．ここで，$\ast$は0でも1でもよく，興味の対象外のビットである．

このようなビットパターンを調べる場合，2つの手順が必要であろう．
%
\begin{enumerate}
 \item まず興味の対象のビットを取り出す必要がある．興味の対象外のビットは，
       \tw{0}または\tw{1}に設定する．
 \item 興味の対象のビットがある特定のビットパターンになっているか，否か比較する．
\end{enumerate}
これを，\tw{AND}と\tw{OR}を使って調べる．

まずは，\tw{AND}を使う方法である．調べたいデータは\tw{GR0}に格納されているとする．
%
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
	                 ;これ以前は省略
	   AND  GR0,A    ;マスク
	   CPL  GR0,B    ;ビットパターンの比較
	                 ;このあたりも省略
	A  DC   #0F0F    ;マスク
	B  DC   #0A0C    ;定数の定義
 \end{verbatim}
\end{quote}

同じ様なことが，ブール代数の双対の原理\footnote{0と1,そして論理和と論理積を入れ
替えても同じことが成り立つ}により，\tw{OR}を使ってもできる．そのほかにも，いろい
ろな方法が考えられる．
%
%---------------------------------------------------------------------
\subsection{プログラムの構造}
%---------------------------------------------------------------------
プログラムの構造については，先に説明した．ほとんど同じである．以下について，答え
よ．
\begin{itemize}
 \item メインルーチンとデータ領域の行番号を答えよ．
 \item ラベルと命令コード，オペランド，コメント文はどれか?
\end{itemize}
%
%---------------------------------------------------------------------
\subsection{フローチャート}
%---------------------------------------------------------------------
このプログラムのフローチャートを図\ref{fig:flow_chart_list5_3}に示す．．
%
\begin{figure}[H]
 \begin{center}
  \includegraphics[keepaspectratio, scale=1.0]{flow_chart/REI5-3.eps}
  \caption{教科書のList5-3のプログラムのフローチャート．}
  \label{fig:flow_chart_list5_3}
 \end{center}
\end{figure}
%
%
%=====================================================================
\section{練習問題}
%=====================================================================
以下の練習問題は，レポートとして提出すること．
\setcounter{toi_num}{1}
\begin{quote}
 \begin{itemize}
  \item[\toi] 加算(I)
	      \begin{itemize}
	       \item{ラベル名AAが示すメモリーの領域に$(10)_{10}$，BBが示
		    す領域に$(30)_{10}$の値を格納する．}
	       \item{それぞれを加算した結果をラベル名WAが示すメモリーの
		   領域に格納する．}
	      \end{itemize}
  \item[\toi] 加算(II)
	      \begin{itemize}
	       \item{ラベル名AAが示すメモリーの領域に$(FF00)_{16}$，BBが示
		    す領域に$(00AB)_{16}$の値を格納する．}
	       \item{それぞれを加算した結果をラベル名WAが示すメモリーの
		    領域に格納する．}
	      \end{itemize}
  \item[\toi] 加算(III)
	      \begin{itemize}
	       \item{ラベル名AAが示すメモリーの領域に$(-50)_{10}$，BBが示
		    す領域に$(10FF)_{16}$の値を格納する．}
	       \item{それぞれを加算した結果をラベル名WAが示すメモリーの
		    領域に格納する．}
	      \end{itemize}
  \item[\toi] 減算(I)
	      \begin{itemize}
	       \item{ラベル名AAが示すメモリーの領域に$(10)_{10}$，BBが示
		    す領域に$(30)_{10}$の値を格納する．}
	       \item{$(10)_{10}-(30)_{10}$の計算結果をラベル名SAが示すメモリーの
		    領域に格納する．}
	      \end{itemize}
  \item[\toi] 減算(II)
	      \begin{itemize}
	       \item{ラベル名AAが示すメモリーの領域に$(-50)_{10}$，BBが示
		    す領域に$(10FF)_{16}$の値を格納する．}
	       \item{$(-50)_{10}-(10FF)_{16}$の計算結果をラベル名SAが示
		    すメモリーの領域に格納する．}
	      \end{itemize}
  \item[\toi] 減算と表示
	      \begin{itemize}
	       \item{ラベル名AAが示すメモリーの領域に$(-50)_{10}$，BBが示
		    す領域に$(10FF)_{16}$の値を格納する．}
	       \item{$(-50)_{10}-(10FF)_{16}$の計算結果をラベル名SAが示
		    すメモリーの領域に格納する．}
	       \item{SAが負の値の場合，MINUSと表示する．正の場合，PLUSと
		    表示する．}
	      \end{itemize}
  \item[\toi] 特定ビットの検査
	      \begin{itemize}
	       \item{ラベル名DATAが示すメモリーの領域に$(FFAA)_{16}$の値
		    を格納する．}
	       \item{マスクを利用して，第15ビット(符号ビット)を検査する．}
	       \item{第15ビットが1の値の場合，MINUSと表示する．0の場合，
		    PLUSと表示する．}
	      \end{itemize}
  \item[\toi] 複数のビットの検査
	      \begin{itemize}
	       \item{ラベル名DATAが示すメモリーの領域に$(A0B9)_{16}$の値
		    を格納する．}
	       \item{マスクを利用して，第15と第0ビットを検査する．}
	       \item{第15ビットが1，第0ビットが0の場合OKと表示する．それ以外の場
		    合，NGと表示する．}
	      \end{itemize}
 \end{itemize}
\end{quote}
% 
%---------------------------------------------------------------------
\subsection{レポート提出要領}
%---------------------------------------------------------------------
提出方法は，次の通りとする．
% 
\begin{quote}
 \begin{tabular}{ll}
  期限 & 2月17日(金) PM 1:00 \\
  用紙 & A4 \\
  提出場所 & 山本研究室の入口のポスト \\
  表紙 & 表紙を1枚つけて，以下の項目を分かりやすく記述すること．\\
       & \qquad 授業科目名「電子計算機」\\
       & \qquad 課題名「課題　プログラム練習(その1)」\\
       & \qquad 3E\quad 学籍番号\quad 氏名\\
       & \qquad 提出日\\
  内容 & 2ページ以降に問いに対する答えを分かりやすく記述すること．
 \end{tabular}
\end{quote}
%
%=====================================================================
%　参考文献
%=====================================================================
\bibliographystyle{jplain}
\bibliography{reference}
%=====================================================================
%
%=====================================================================
\end{document}



