210 lines
12 KiB
TeX
210 lines
12 KiB
TeX
\chapter{Instruction Set Architecture}
|
|
Instructions are variable width with their total length being determined by the mode setting byte that immediately follows the opcode byte. A break down of what a nibble means in the mode setting byte can be found in Figure \ref{fig:ModeSettingEncodingFigure}. Figure \ref{fig:opencoding} shows the layout of an instruction with the mode setting byte split down the middle to indicate the top nibble defines what \textit{Operand One} is meant to be interpreted as, followed by the lower nibble for \textit{Operand Two}. Depending on what mode is set for each operand there may be no bytes to follow the instruction (like in the case of nop) or there may be 8 bytes to follow (like in the case of mov [address], [address], assuming absolute addresses).
|
|
|
|
\newcommand{\OpcodeTable}[5] {
|
|
\noindent
|
|
\begin{minipage}{\textwidth}
|
|
\begin{tabularx}{\textwidth}{ | X | X | X | X | }
|
|
\hline
|
|
Opcode Hex & Instruction & Operand 1 & Operand 2 \\
|
|
\hline
|
|
#1 & #2 & #3 & #4 \\
|
|
\hline
|
|
\end{tabularx}
|
|
\paragraph{Description} #5
|
|
\end{minipage}
|
|
}
|
|
|
|
\def\gap{0.25pt}
|
|
\def\minX{0}\def\maxX{\textwidth}
|
|
\def\minY{-0.25}\def\maxY{0.25}
|
|
\def\lnWidth{\textwidth / 4}
|
|
|
|
\section{Instruction Layout}
|
|
|
|
% Placement info here: https://en.wikibooks.org/wiki/LaTeX/Floats,_Figures_and_Captions#Figures
|
|
% Paths: https://tikz.dev/tikz-paths
|
|
\begin{figure}[ht]
|
|
\begin{tikzpicture}
|
|
%Opcode Byte
|
|
\draw (\minX, 0) -- (\lnWidth, 0) node[midway, below=1em] {Opcode};
|
|
\draw (\minX, \minY) node[below] {7} -- (\minX, \maxY);
|
|
\draw (\lnWidth, \minY) -- (\lnWidth, \maxY) node[above] {7};
|
|
%Mode setting byte
|
|
\draw (\lnWidth, 0) -- (\lnWidth * 2, 0) node[midway, above=1em] (ModeSettingByteLabel) {Mode};
|
|
\draw node[above of=ModeSettingByteLabel] {(if required)};
|
|
\draw (\lnWidth, \minY) node[below] {0} -- (\lnWidth, \maxY);
|
|
\draw (\lnWidth * 2, \minY) node[below] {0} -- (\lnWidth * 2, \maxY);
|
|
\draw (\lnWidth + \lnWidth / 2, \minY) node[below] (ModeByteMiddleLabel) {4 3} -- (\lnWidth + \lnWidth / 2, \maxY);
|
|
%Operand One
|
|
\draw (\lnWidth * 2, 0) -- (\lnWidth * 3, 0) node[midway, below=1em] (OperOneLabel) {Operand One};
|
|
\draw (\lnWidth * 2, \minY) -- (\lnWidth * 2, \maxY) node[above] {31/15/7};
|
|
\draw (\lnWidth * 3, \minY) node[below] {0} -- (\lnWidth * 3, \maxY);
|
|
\draw node[below of=OperOneLabel] {(if required)};
|
|
%Operand Two
|
|
\draw (\lnWidth * 3, 0) -- (\lnWidth * 4, 0) node[midway, below=1em] (OperTwoLabel) {Operand Two};
|
|
\draw (\lnWidth * 3, \minY) -- (\lnWidth * 3, \maxY) node[above] {31/15/7} node[above=1.5em] {Operand Widths Based on Mode};
|
|
\draw (\textwidth, \minY) node[below] {0} -- (\textwidth, \maxY);
|
|
\draw node[below of=OperTwoLabel] {(if required)};
|
|
\end{tikzpicture}
|
|
\caption{Encoding}
|
|
\label{fig:opencoding} % https://www.overleaf.com/learn/latex/Referencing_Figures
|
|
\paragraph{Note} Figure \ref{fig:ModeSettingEncodingFigure} shows the options for the \textit{Mode} byte.
|
|
\end{figure}
|
|
|
|
\def\registerBit{0}\def\registerBitA{8}
|
|
\def\eightBit{1}\def\eightBitA{9}
|
|
\def\sixteenBit{2}\def\sixteenBitA{A}
|
|
\def\thirtyBit{4}\def\thirtyBitA{C}
|
|
\def\none{F}
|
|
|
|
\begin{figure}
|
|
\begin{tabularx}{\textwidth}{ | X | X | X | }
|
|
\hline
|
|
Operand & Immediate Value & Value As Address \\
|
|
\hline
|
|
Register & \xintCHexToBin{\registerBit} & \xintCHexToBin{\registerBitA} \\
|
|
8-Bit & \xintCHexToBin{\eightBit} & \xintCHexToBin{\eightBitA} \\
|
|
16-Bit & \xintCHexToBin{\sixteenBit} & \xintCHexToBin{\sixteenBitA} \\
|
|
32-Bit & \xintCHexToBin{\thirtyBit} & \xintCHexToBin{\thirtyBitA} \\
|
|
None & \xintCHexToBin{\none} & \xintCHexToBin{\none} \\
|
|
\hline
|
|
\end{tabularx}
|
|
\caption{Operand Modes Bit Pattern}
|
|
\label{fig:ModeSettingEncodingFigure} % https://www.overleaf.com/learn/latex/Referencing_Figures
|
|
\end{figure}
|
|
\clearpage
|
|
\section{Instructions}
|
|
The /r represents a byte that specifies a register. /immX is for the immediate data type, where \textit{X} defines the width, which are 8, 16, or 32 bits. An address is defined as /addrX with the \textit{X} denoting the size of the data that will be written which can be 8, 16 or 32 bits, with the address itself always being 32-bits wide.
|
|
\subsection{Add}
|
|
\begin{tabularx}{\textwidth}{ | c | X | c | c | }
|
|
\hline
|
|
Opcode & Instruction & Operand One & Operand Two \\
|
|
\hline
|
|
01 \registerBit\registerBit & add /r, /r & /r & /r \\
|
|
01 \eightBit\registerBit & add /imm8, /r & /imm8 & /r \\
|
|
01 \sixteenBit\registerBit & add /imm16, /r & /imm16 & /r \\
|
|
01 \thirtyBit\registerBit & add /imm32, /r & /imm32 & /r \\
|
|
\hline
|
|
\end{tabularx}
|
|
\paragraph{Description} Adds two unsigned values together, the source (operand one) and the destination (operand two), storing the result in destination. The overflow flag (OF) is set if the result is less than the source and the zero flag (ZF) is set when the result of addition is zero.
|
|
\paragraph{Flags Affected} OF and ZF.
|
|
\subsection{Sub}
|
|
\begin{tabularx}{\textwidth}{ | c | X | c | c | }
|
|
\hline
|
|
Opcode & Instruction & Operand One & Operand Two \\
|
|
\hline
|
|
02 \registerBit\registerBit & sub /r, /r & /r & /r \\
|
|
02 \eightBit\registerBit & sub /imm8, /r & /imm8 & /r \\
|
|
02 \sixteenBit\registerBit & sub /imm16, /r & /imm16 & /r \\
|
|
02 \thirtyBit\registerBit & sub /imm32, /r & /imm32 & /r \\
|
|
\hline
|
|
\end{tabularx}
|
|
\paragraph{Description} Subtracts two unsigned values, the source (operand one) and the destination (operand two), storing the result in destination. The underflow flag (UF) is set if the result is greater than the source and the zero flag (ZF) is set when the result of subtraction is zero.
|
|
\paragraph{Flags Affected} UF and ZF.
|
|
\subsection{Mul}
|
|
\begin{tabularx}{\textwidth}{ | c | X | c | c | }
|
|
\hline
|
|
Opcode & Instruction & Operand One & Operand Two \\
|
|
\hline
|
|
03 \registerBit\registerBit & mul /r, /r & /r & /r \\
|
|
03 \eightBit\registerBit & mul /imm8, /r & /imm8 & /r \\
|
|
03 \sixteenBit\registerBit & mul /imm16, /r & /imm16 & /r \\
|
|
03 \thirtyBit\registerBit & mul /imm32, /r & /imm32 & /r \\
|
|
\hline
|
|
\end{tabularx}
|
|
\paragraph{Description} Multiplies two unsigned values together, the source (operand one) and the destination (operand two), storing the result in destination. The overflow flag (OF) is set if the result is less than the source and the zero flag (ZF) is set when the result of addition is zero.
|
|
\paragraph{Flags Affected} OF and ZF.
|
|
\subsection{Div}
|
|
\begin{tabularx}{\textwidth}{ | c | X | c | c | }
|
|
\hline
|
|
Opcode & Instruction & Operand One & Operand Two \\
|
|
\hline
|
|
04 \registerBit\registerBit & div /r, /r & /r & /r \\
|
|
04 \eightBit\registerBit & div /imm8, /r & /imm8 & /r \\
|
|
04 \sixteenBit\registerBit & div /imm16, /r & /imm16 & /r \\
|
|
04 \thirtyBit\registerBit & div /imm32, /r & /imm32 & /r \\
|
|
\hline
|
|
\end{tabularx}
|
|
\paragraph{Description} Divides two unsigned values, the source (operand one) and the destination (operand two), storing the result in destination. The underflow flag (UF) is set if the result is greater than the source and the zero flag (ZF) is set when the result of subtraction is zero.
|
|
\paragraph{Flags Affected} UF and ZF.
|
|
\subsection{Mov}
|
|
\begin{tabularx}{\textwidth}{ | c | X | c | c | }
|
|
\hline
|
|
Opcode & Instruction & Operand One & Operand Two \\
|
|
\hline
|
|
05 \registerBit\registerBit & mov /r, /r & /r & /r \\
|
|
05 \registerBit\eightBitA & mov /r, /addr8 & /r & /addr8 \\
|
|
05 \registerBit\sixteenBitA & mov /r, /addr16 & /r & /addr16 \\
|
|
05 \registerBit\thirtyBitA & mov /r, /addr32 & /r & /addr32 \\
|
|
|
|
05 \registerBitA\registerBit & mov [/r], /r & [/r] & /r \\
|
|
05 \registerBitA\eightBitA & mov [/r], /addr8 & [/r] & /addr8 \\
|
|
05 \registerBitA\sixteenBitA & mov [/r], /addr16 & [/r] & /addr16 \\
|
|
05 \registerBitA\thirtyBitA & mov [/r], /addr32 & [/r] & /addr32 \\
|
|
|
|
05 \eightBitA\registerBit & mov /addr8, /r & /addr8 & /r \\
|
|
05 \sixteenBitA\registerBit & mov /addr16, /r & /addr16 & /r \\
|
|
05 \thirtyBitA\registerBit & mov /addr32, /r & /addr32 & /r \\
|
|
|
|
05 \eightBit\registerBit & mov /imm8, /r & /imm8 & /r \\
|
|
05 \eightBit\registerBitA & mov /imm8, [/r] & /imm8 & [/r] \\
|
|
05 \eightBit\eightBitA & mov /imm8, /addr8 & /imm8 & /addr8 \\
|
|
05 \eightBit\sixteenBitA & mov /imm8, /addr16 & /imm8 & /addr16 \\
|
|
05 \eightBit\thirtyBitA & mov /imm8, /addr32 & /imm8 & /addr32 \\
|
|
|
|
05 \sixteenBit\registerBit & mov /imm16, /r & /imm16 & /r \\
|
|
05 \sixteenBit\registerBitA & mov /imm16, [/r] & /imm16 & [/r] \\
|
|
05 \sixteenBit\sixteenBitA & mov /imm16, /addr16 & /imm16 & /addr16 \\
|
|
05 \sixteenBit\thirtyBitA & mov /imm16, /addr32 & /imm16 & /addr32 \\
|
|
|
|
05 \thirtyBit\registerBit & mov /imm32, /r & /imm32 & /r \\
|
|
05 \thirtyBit\registerBitA & mov /imm32, [/r] & /imm32 & [/r] \\
|
|
05 \thirtyBit\thirtyBitA & mov /imm32, /addr32 & /imm32 & /addr32 \\
|
|
\hline
|
|
\end{tabularx}
|
|
\paragraph{Description} Copies the source (operand one) value to the destination (operand two).
|
|
\paragraph{Flags Affected} None.
|
|
\subsection{AND}
|
|
\OpcodeTable{01 /r /r}{and /r, /r}{Register}{Register}{Bit-wise ANDs \textit{Operand 1} and \textit{Operand 2} placing the result into \textit{Operand 1}.}
|
|
\subsection{OR}
|
|
\OpcodeTable{01 /r /r}{or /r, /r}{Register}{Register}{Bit-wise ORs \textit{Operand 1} and \textit{Operand 2} placing the result into \textit{Operand 1}.}
|
|
\subsection{XOR}
|
|
\OpcodeTable{01 /r /r}{xor /r, /r}{Register}{Register}{Bit-wise exclusive ORs \textit{Operand 1} and \textit{Operand 2} placing the result into \textit{Operand 1}.}
|
|
\subsection{NOT}
|
|
\OpcodeTable{01 /r}{not /r}{Register}{None}{Bit-wise negates \textit{Operand 1} placing the result into \textit{Operand 1}.}
|
|
\subsection{SHL}
|
|
\OpcodeTable{01 /r /i8}{shl /r, /i8}{Register}{Immediate}{Shifts the bits of \textit{Operand 1} left \textit{Operand 2} times.}
|
|
\subsection{SHR}
|
|
\OpcodeTable{01 /r /i8}{shr /r, /i8}{Register}{Immediate}{Shifts the bits of \textit{Operand 1} right \textit{Operand 2} times.}
|
|
|
|
\subsection{NOP}
|
|
\OpcodeTable{01}{nop}{None}{None}{No operation, increments the Program Counter by one.}
|
|
%Oh this control flow will be interesting, juggling flags is not something I'm used to.
|
|
\subsection{CMP}
|
|
\OpcodeTable{01 /mod /r /r}{cmp /r, /r}{Register}{Register}{Subtracts \textit{Operand 2} from \textit{Operand 1} setting the Zero Flag if the result is zero. If \textit{Operand 2} is larger then the Sign Flag is set, otherwise the Sign Flag will be cleared.}
|
|
\subsection{JMP}
|
|
\OpcodeTable{01 /mod /i32}{jmp /i32}{Immediate}{None}{Unconditionally jumps to address \textit{Operand 1}.}
|
|
\subsection{JZ}
|
|
\OpcodeTable{01 /i32}{jz /i32}{Immediate}{None}{Jumps to address \textit{Operand 1} if the Zero Flag is set.}
|
|
\subsection{JG}
|
|
\OpcodeTable{01 /mod /i32}{jg /i32}{Immediate}{None}{Jumps to address \textit{Operand 1} if the Sign Flag is set.}
|
|
\subsection{JL}
|
|
\OpcodeTable{01 /mod /i32}{jl /i32}{Immediate}{None}{Jumps to address \textit{Operand 1} if the Sign Flag is not set.}
|
|
|
|
%Maybe these in/out instructions could have a mode setting for choosing the width of the data written to the port.
|
|
\subsection{Outb}
|
|
\OpcodeTable{01 /r /r}{add /r, /r}{8-Bit}{Register}{Writes an 8-bit value from \textit{Operand 2} into port number \textit{Operand 1}.}
|
|
\subsection{Inb}
|
|
\OpcodeTable{01 /r /r}{inb /r, /r}{Register}{8-Bit}{Reads an 8-bit byte from the port number \textit{Operand 2}, writing it into \textit{Operand 1}.}
|
|
|
|
\subsection{HLT}
|
|
\OpcodeTable{01}{hlt}{None}{None}{Halts the processor until a new interrupt is received.}
|
|
\subsection{CLI}\label{sec:cli}
|
|
\OpcodeTable{01}{cli}{None}{None}{Clears the interrupt flag preventing the processor from receiving interrupts.}
|
|
\subsection{ENI}\label{sec:eni}
|
|
\OpcodeTable{01}{eni}{None}{None}{Sets the interrupt flag allowing the processor to receive interrupts.}
|
|
\subsection{INT}\label{sec:int}
|
|
\OpcodeTable{01 /i8}{int /i8}{Immediate}{None}{Triggers software interrupt number \textit{Operand 1}.}
|
|
\subsection{LIVT}\label{sec:livt}
|
|
\OpcodeTable{00 /mod /i32}{livt /i32}{Immediate}{None}{Installs the Interrupt Vector Table located at memory address \textit{Operand 1}.} |