%=====================================================================
% 秋田高専 3E 電子計算機用テキスト
%    サブルーチン・スタック関係命令
%      last updated 2006.1.31
%        created by  Masashi Yamamoto
%        e-mail yamamoto@akita-nct.jp
%=====================================================================
\documentclass[10pt,a4paper]{jarticle}
\usepackage{graphicx,amsmath,amssymb,ascmac,float}
\usepackage{html, listings, jlisting}
\usepackage{url}
\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{機械語命令(スタック・サブルーチン・他)}
\date{2005年1月31日}
\author{山本昌志\thanks{国立秋田工業高等専門学校　電気工学科}}
\maketitle
%
%=====================================================================
\section{前回の復習と本日の学習}
%=====================================================================
%---------------------------------------------------------------------
\subsection{復習}
%---------------------------------------------------------------------
今まで，学習したCOMET IIの命令は，次の通りである．これを思い出して，本日の学習内
容と絡めて，理解を深める必要がある．
%
%----------------------------
\subsubsection{アセンブラ命令}
%----------------------------
\begin{itemize}
 \item[]
	\begin{tabular}{p{20mm}p{15mm}p{90mm}}
	 開始    & \tw{START} & プログラムの先頭を示し，入口名と実行開始番地を定義\\
	 終了    & \tw{END}   & プログラムの終わりを明示\\
	 領域確保 & \tw{DS} & プログラムで使うメインメモリーを予約\\
	 定義    & \tw{DC} & メインメモリーの初期値設定 \\
	\end{tabular}
\end{itemize}
%----------------------------
\subsubsection{機械語命令}
%----------------------------
\begin{itemize}
 \item データ転送命令\\
       \begin{tabular}{p{20mm}p{15mm}p{90mm}}
	データ転送 & \tw{LD} & メインメモリーやレジスターの内容を汎用レジスタに転送
	\\
	データ転送 & \tw{ST} & 汎用レジスタのデータをメインメモリーへ転送 \\
	アドレス転送 & \tw{LAD} & 実効アドレスを汎用レジスターへ転送 \\
       \end{tabular}
 \item 算術，論理演算\\
       \begin{tabular}{p{20mm}p{15mm}p{90mm}}
	算術加算 & \tw{ADDA} & 1語のデータを符号付き整数と見なし，加算を行う．
	\\
	論理加算 & \tw{ADDL} & 1語のデータを符号無し整数と見なし，加算を行う．\\
	算術減算 & \tw{SUBA} & 1語のデータを符号付き整数と見なし，減算を行う．
	\\
	算術減算 & \tw{SUBL} & 1語のデータを符号無し整数と見なし，減算を行う．
	\\
	論理積 & \tw{AND} & 1語のデータのビット毎の論理積の演算を行う．\\
	論理和 & \tw{OR} & 1語のデータのビット毎の論理和の演算を行う．\\
	排他的論理和 & \tw{XOR} & 1語のデータのビット毎の排他的論理和の演算を行う．\\
       \end{tabular}
 \item シフト\\
       \begin{tabular}{p{20mm}p{15mm}p{90mm}}
	算術左シフト & \tw{SLA} &
	レジスタの内容を符号ビットを除き左にシフト．空きには0が入る．\\
	%
	算術右シフト & \tw{SRA} &
	レジスタの内容を符号ビットを除き左にシフト．空きには符号ビットが入る\\
	%
	論理左シフト & \tw{SLL} &
	1語全てを，左にシフト．空きには0が入る\\
	%
	論理右シフト & \tw{SRL} &
	1語全てを，右にシフト．空きには0が入る\\
       \end{tabular}
 \item 比較\\
       \begin{tabular}{p{20mm}p{15mm}p{90mm}}
	算術比較 & \tw{CPA} &
	データは符号付き整数と見なし，比較を行う．\\
	論理比較 & \tw{CPL} &
	データは符号無し整数と見なし，比較を行う．
       \end{tabular}
 \item 分岐\\
       \begin{tabular}{p{20mm}p{15mm}p{90mm}}
	正分岐 & \tw{JPL} &
	\tw{SF}と\tw{ZF}がともに0の時，指定の実効アドレスに分岐\\
	%
	負分岐 & \tw{JMI} &
	\tw{SF}が１の時，指定の実効アドレスに分岐\\
	%
	非零分岐 & \tw{JNZ} &
	\tw{ZF}が0の時，指定の実効アドレスに分岐\\
	%
	零分岐 & \tw{JZE} &
	\tw{ZF}が1の時，指定の実効アドレスに分岐\\
	%
	オーバーフロー分岐 & \tw{JOV} &
	\tw{OF}が1の時，指定の実効アドレスに分岐\\
	%
	無条件分岐 & \tw{JUMP} &
	無条件に，指定の実効アドレスに分岐
       \end{tabular}
\end{itemize}
%---------------------------------------------------------------------
\subsection{本日の学習内容}
%---------------------------------------------------------------------
教科書~\cite{text_casl2}のp.76〜p.82までである．
%--------------------------
\subsubsection{スタック操作}
%--------------------------
スタックの操作は．サブルーチンを呼び出すときにデータを待避させる時に主に使う．
%
 \begin{quote}
  \begin{tabular}{p{25mm}p{15mm}p{80mm}}
   \textbf{プッシュ} & \tw{PUSH} &
   スタックにデータを入れる(プッシュする)\\
   \textbf{ポップ} & \tw{PUSH} &
   スタックにデータを取り出す(ポップする)\\
  \end{tabular}
 \end{quote}
%-------------------------------
\subsubsection{サブルーチン関係}
%-------------------------------
比較とジャンプ命令は，セットで使われることが多く，数の比較を行い，その結果を受け
て，処理の実行を変える．FORTRANやC言語では，
\begin{quote}
 \begin{tabular}{p{25mm}p{15mm}p{80mm}}
  \textbf{コール} & \tw{CALL} &
  サブルーチンを呼び出す(コールする)\\
  \textbf{リターン} & \tw{RET} &
  呼び出し元へ復帰する(リターンする)
 \end{tabular}
\end{quote}
%-------------------------------
\subsubsection{その他}
%-------------------------------
\begin{quote}
 \begin{tabular}{p{25mm}p{15mm}p{80mm}}
  \textbf{スーパーバイザーコール} & \tw{SVC} &
  OSの機能を呼び出す\\
  \textbf{ノンオペレーション} & \tw{NOP} &
  なにも実行しない
 \end{tabular}
\end{quote}
%
%=====================================================================
\section{スタック操作}
%=====================================================================
%---------------------------------------------------------------------
\subsection{スタックとは}
%---------------------------------------------------------------------
スタック(stack)を辞書で調べてみると，次のような意味が書かれている．
\begin{enumerate}
 \item (干し草などの)大きな山，積みわら(haystack);(物のきちんとした)積み重ね
 \item (図書館などの)書棚の列，書架；((the 〜s)) (図書館の)(閉架)書庫
 \item (屋上の)組み合わせ煙突(chimney stack);煙突，煙出し
 \item 《コンピューター》スタック:最後に入れたデータを最初に取り出せるようにしたデータ構造
\end{enumerate}
もちろん，情報科学の分野で使われるのは最後の意味で，図\ref{fig:stack}のようなデータ構造で
ある．データ構造であるから，データを蓄えることと，それを取り出すことができる．ス
タックの特徴は，最後に入れたデータが一番最初に取り出されることにある．取り出され
るデータは，格納されている最新のデータで，最後に入れられたものが最初に取り出され
ることから，LIFO(last in first out, 後入れ先出し)と呼ばれる．スタックの途中のデー
タを取り出すことは許されないのである．

スタックにデータを積むことをプッシュ(push)と，スタックからデータを取り出すことを
ポップ(pup)と呼ぶ．これらの英語の意味は，
\begin{description}
 \item[push]＜人・物を＞押す，突く
 \item[pop]ポンという音を立てる，ひょいとやって来る[出て行く]，急にはいる[出る],
	    ひょっこり現れる
\end{description}
である．
%
\begin{figure}[H]
 \begin{center}
  \includegraphics[keepaspectratio,scale=1.0]
  {figure/stack.eps}
  \caption{スタックのイメージ．メモリーへデータの出し入れをする．}
  \label{fig:stack}
 \end{center}
\end{figure}

COMET IIの場合，スタック領域は主記憶(メインメモリー)のどこかに必要量確保されてい
る．確保されているアドレスはプログラマーは気にすることなく，\tw{PUSH}と\tw{POP}
の命令を使うことができる．実際にスタック領域の最上位のアドレスは\tw{SP}(スタック
ポインター)に格納されており，その操作はOSの仕事である．
%
%---------------------------------------------------------------------
\subsection{スタックの利用方法}
%---------------------------------------------------------------------
スタックは極めて単純なデータ構造なので，それを実際のコンピューターに実装すること
は易しい．単純ではあるが，それはかなり頻繁に使われる．もっとも多く使われるのが，
サブルーチンを呼び出すときに，一時的にデータを避難させる場合である．実際にはコン
パイルした後で出てくるのでプログラマーが直に記述することは少ないが，本当によく使
われている．

CASL IIのプログラムでもっとも多く使われる場面は，サブルーチンを呼び出すときにデー
タを一時的に雛させる場合である．これについては，後ほど，実際のプログラムで学習す
ることになる．
%
%---------------------------------------------------------------------
\subsection{スタックを操作する命令}
%---------------------------------------------------------------------
%--------------------------------------
\subsubsection{プッシュ(\tw{PUSH})}
%-------------------------------------
%--------------------
\paragraph{内容}
%--------------------
\begin{quote}
 \begin{tabular}{p{30mm}p{100mm}}
  \textbf{命令語}  & \tw{POP} \\
  \textbf{語源}   & \textbf{POP}\hspace{5mm}(push:押す)\\
  %
  \textbf{役割}     & スタック領域にデータを格納する．\\
  \textbf{書式}     & [ラベル]\hspace{5mm}\tw{PUSH}\hspace{5mm}{\it adr}[,x] \\
  \textbf{動作}     & SPの値を1減らす．そして，スタック領域へアドレスを格納する．
  \\
  \textbf{フラグレジスタ} & 変化無し．
  %
 \end{tabular}
\end{quote}
%
%--------------------
\paragraph{使用例}
%--------------------
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
      PUSH   DATA         ;DATAが示すアドレスをスタック領域に格納
      PUSH   23           ;23をスタック領域に格納
      PUSH   0,GR1        ;GR1の内容をスタック領域に格納
 \end{verbatim}
\end{quote}
%
%--------------------------------------
\subsubsection{ポップ(\tw{POP})}
%-------------------------------------
%--------------------
\paragraph{内容}
%--------------------
\begin{quote}
 \begin{tabular}{p{30mm}p{100mm}}
  \textbf{命令語}  & \tw{POP} \\
  \textbf{語源}   & \textbf{POP}\hspace{5mm}(pop:出る)\\
  %
  \textbf{役割}     & スタック領域からデータを取り出す．\\
  \textbf{書式}     & [ラベル]\hspace{5mm}\tw{POP}\hspace{5mm}r \\
  \textbf{動作}     & スタックポインター\tw{SP}が示しているアドレスの内容を取り
  出してレジスターに格納する．そして，\tw{SP}の値を1増やす．
  \\
  \textbf{フラグレジスタ} & 変化無し．
  %
 \end{tabular}
\end{quote}
%
%--------------------
\paragraph{使用例}
%--------------------
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
      PUP    GR1        ;スタック領域の最上段の値をGR1へ格納
 \end{verbatim}
\end{quote}
%
%=====================================================================
\section{サブルーチン関係}
%=====================================================================
%---------------------------------------------------------------------
\subsection{サブルーチンとは}
%---------------------------------------------------------------------
大量のパーツからできている自動車も機能別の部品に分けることにより，その構造が分か
りやすくなる．例えば，エンジン，トランスミッション，サスペンション等，機能毎に説
明されると分かりやすい．一つ一つの部品，例えば，ボルト，ベルト，シャフトの説明を
されても自動車の全体は分からない．自動車の仕組みを分かるためには，機能毎に理解す
る方が断然簡単である．

プログラムも一緒である．それを構成する機能の集まりで理解した方が簡単である．
Windowsの4千万行もあるプログラムの各行を説明されても全く分からない．プログラムを
機能毎に分けたものがサブルーチンと呼ばれるものの本質である．要するにプログラムを
構成する機能単位の部品だと思えばよい．

図\ref{fig:only_main}と\ref{fig:with_subroutine}にサブルーチンを使ったプログラム
とそうでないプログラムのイメージを示す．圧倒的に，サブルーチンを使った図
\ref{fig:with_subroutine}の方が見通しがよい．実際に長いプログラムを書く場合，サ
ブルーチンを使わないと不可能である．

具体的に，プログラムを機能別のサブルーチンに分けると，以下のようなメリットがあ
る．
\begin{itemize}
 \item プログラムの作成が容易になる．
 \item プログラムの内容が分かりやすくなる．
 \item サブルーチンの再利用が容易になる．
\end{itemize}
ちろんCASL IIにもこれが当てはまり，出来るだけ機能毎にプログラムを書くようにす
べきである．要するにサブルーチンを使えということである．
%
\begin{figure}[H]
 \begin{tabular}{cc}
 %--------- メインルーチンのみ ----------------------------
  \begin{minipage}[b]{0.35\hsize}
   \begin{center}
   \vspace*{1mm}
    \includegraphics[keepaspectratio, scale=1.0]{figure/only_main.eps}
    \caption{メインルーチンだけのプログラム}
    \label{fig:only_main}
   \end{center}
  \end{minipage} &
  %--------- サブルーチンを使う -----------------------------
  \begin{minipage}[b]{0.65\hsize}
   \vspace*{1mm}
   \begin{center}
    \includegraphics[keepaspectratio, scale=1.0]{figure/with_subroutine.eps}
    \caption{機能毎(サブルーチン)に分割されたプログラム．矢印は，デー
    タの流れをあらわす．}
    \label{fig:with_subroutine}
   \end{center}
  \end{minipage}
 \end{tabular}
\end{figure}
%
%---------------------------------------------------------------------
\subsection{サブルーチンを操作する命令}
%---------------------------------------------------------------------
サブルーチンを呼び出す命令\tw{CALL}とサブルーチンから戻る命令\tw{RET}は，ペアで
使われる．アセンブラ命令\tw{START}で指定される最初に実行されるルーチン\footnote
{メインルーチン}もOSがコールする．プログラム中ではあらわに現れないが，やはり
\tw{CALL}と\tw{RET}のペアになっているのである．
%--------------------------------------
\subsubsection{コール(\tw{CALL})}
%-------------------------------------
%--------------------
\paragraph{内容}
%--------------------
\begin{quote}
 \begin{tabular}{p{30mm}p{100mm}}
  \textbf{命令語}  & \tw{CALL} \\
  \textbf{語源}   & \textbf{CALL}\hspace{5mm}(call:呼ぶ)\\
  \textbf{役割}     & サブルーチンへ制御を移す．\\
  \textbf{書式}     & [ラベル]\hspace{5mm}\tw{CALL}\hspace{5mm}{\it adr}[,x] \\
  \textbf{動作}     & プログラムレジスタ\tw{PR}の値を指定のアドレスに変える．現
  在のアドレスはスタック領域に待避させる．
  \\
  \textbf{フラグレジスタ} & 変化無し．
 \end{tabular}
\end{quote}
%
%--------------------
\paragraph{使用例}
%--------------------
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
      CALL   KAKEZAN         ;アドレスKAKEZANを呼び出し
 \end{verbatim}
\end{quote}
%
%--------------------------------------
\subsubsection{リターン(\tw{RET})}
%-------------------------------------
%--------------------
\paragraph{内容}
%--------------------
\begin{quote}
 \begin{tabular}{p{30mm}p{100mm}}
  \textbf{命令語}  & \tw{RET} \\
  \textbf{語源}   & \textbf{RET}urn\hspace{5mm}(return:帰る，戻る)\\
  \textbf{役割}     & サブルーチンから呼び出し元へ制御が戻る．\\
  \textbf{書式}     & [ラベル]\hspace{5mm}\tw{RET} \\
  \textbf{動作}     & スタックポインター(\tw{SP})が示すアドレスの値をプログラム
  レジスター(PR)にセットする．そして，\tw{PR}の値を，1増加させる．
  \\
  \textbf{フラグレジスタ} & 変化無し．
 \end{tabular}
\end{quote}
%
%--------------------
\paragraph{使用例}
%--------------------
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
      RET         ;呼び出し元へ戻る
 \end{verbatim}
\end{quote}
%
%=====================================================================
\section{その他の命令}
%=====================================================================
%--------------------------------------
\subsubsection{スーパーバイザーコール(\tw{SVC})}
%-------------------------------------
%--------------------
\paragraph{内容}
%--------------------
\begin{quote}
 \begin{tabular}{p{30mm}p{100mm}}
  \textbf{命令語}  & \tw{SVC} \\
  \textbf{語源}   & \textbf{S}uper\textbf{V}isor \textbf{C}all
  \hspace{5mm}(supervisor:監督者，管理人)\\
  \textbf{役割}     & OSの機能を呼び出す．\\
  \textbf{書式}     & [ラベル]\hspace{5mm}\tw{SVC}\hspace{5mm}{\it adr}[,x] \\
  \textbf{動作}     & 指定されたアドレスをコールする．\\
  \textbf{フラグレジスタ} & アセンブラーに依存．
 \end{tabular}
\end{quote}
%
%--------------------
\paragraph{使用例}
%--------------------
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
      SVC  #A000       ;A000へジャンプ
 \end{verbatim}
\end{quote}
%
OSの機能(サブルーチンみたいなもの)へ制御を移すので，実際の動作はOSに依存する．諸
君はこの機能を使うことはないだろう．諸君が使っているシミュレーターの機能をよく調
べて使うなら別である．
%--------------------------------------
\subsubsection{ノーオペレーション(\tw{NOP})}
%-------------------------------------
%--------------------
\paragraph{内容}
%--------------------
\begin{quote}
 \begin{tabular}{p{30mm}p{100mm}}
  \textbf{命令語}  & \tw{NOP} \\
  \textbf{語源}   & \textbf{N}o \textbf{OP}eration \hspace{5mm}(operatin:操作，
  演算)\\
  \textbf{役割}     & 何もしない．\\
  \textbf{書式}     & [ラベル]\hspace{5mm}\tw{NOP} \\
  \textbf{動作}     & プログラムレジスター(\tw{PR})の値を1増加させる．\\
  \textbf{フラグレジスタ} & 変化無し．
 \end{tabular}
\end{quote}
%
%--------------------
\paragraph{使用例}
%--------------------
\begin{quote}
 \setlength{\baselineskip}{12pt}
 \begin{verbatim}
   L1  NOP       ;何もしないが，ラベルは有効
 \end{verbatim}
\end{quote}
%
この命令は，なにも動作はしない．しかし，ラベルは有効であるため，ラベルを付けたい
場合に使われる．
%=====================================================================
%  参考文献
%=====================================================================
\bibliographystyle{jplain}
\bibliography{reference}
%=====================================================================
\end{document}



