From 892e34af937bffdcf31511a56c49de90adc25a07 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Tue, 3 Sep 2024 23:21:14 -0500 Subject: [PATCH] Fleshed out and updated all the current instructions' opcodes, arguments and functions. --- chapter 2.tex | 269 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 231 insertions(+), 38 deletions(-) diff --git a/chapter 2.tex b/chapter 2.tex index 304c7b5..8317e42 100644 --- a/chapter 2.tex +++ b/chapter 2.tex @@ -1,19 +1,6 @@ \chapter{Instruction Set Architecture} Instructions are variable width with most instructions' width being determined by the \textit{mode} byte that follows immediately after the opcode byte. The \textit{mode} byte is split into four parts, with the upper nibble describing what the types of source and destination operands the instruction is to deal with. Following those four bits is two reserved bits and finally the final two bits in the least significant half of the lower nibble, the \textit{source width}. Depending on the \textit{source type} bits, the next number of bytes to be read for the source operand can be 8-, 16- or 32-bits and the same applies to the \textit{destination type} bits. A more visual layout of this may be found in Figure \ref{fig:opencoding}. -\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} -} \section{Instruction Layout} % Placement info here: https://en.wikibooks.org/wiki/LaTeX/Floats,_Figures_and_Captions#Figures % Paths: https://tikz.dev/tikz-paths @@ -79,9 +66,9 @@ Instructions are variable width with most instructions' width being determined b Type & Pattern & Description \\ \hline Register & 00 & Operand is a register \\ - \&Register & 01 & Operand is a 32-bit address stored in a register \\ + {[Register]} & 01 & Operand is a 32-bit address stored in a register \\ Immediate & 10 & Operand is an 8-, 16- or 32-bit value \\ - Address & 11 & Operand is a 32-bit address \\ + {[Immediate]} & 11 & Operand is treated as a 32-bit address \\ \hline \multicolumn{3}{ | X | }{Source Operand Width Patterns} \\ \hline @@ -162,50 +149,256 @@ The /r represents a byte that specifies a register. /immX is for the immediate d \hline Opcode & Instruction & Operand One & Operand Two \\ \hline + 05 \rRArgH\byteWidthH & mov byte /r, /r & /r & /r \\ + 05 \rRArgH\shortWidthH & mov short /r, /r & /r & /r \\ + 05 \rRArgH\intWidthH & mov (int) /r, /r & /r & /r \\ + 05 \rRaArgH\byteWidthH & mov byte /r, [/r] & /r & [/r] \\ + 05 \rRaArgH\shortWidthH & mov short /r, [/r] & /r & [/r] \\ + 05 \rRaArgH\intWidthH & mov (int) /r, [/r] & /r & [/r] \\ + 05 \rAArgH\byteWidthH & mov byte /r, [imm32] & /r & [imm32] \\ + 05 \rAArgH\shortWidthH & mov short /r, [imm32] & /r & [imm32] \\ + 05 \rAArgH\intWidthH & mov (int) /r, [imm32] & /r & [imm32] \\ + + 05 \raRArgH\byteWidthH & mov byte [/r], /r & [/r] & /r \\ + 05 \raRArgH\shortWidthH & mov short [/r], /r & [/r] & /r \\ + 05 \raRArgH\intWidthH & mov (int) [/r], /r & [/r] & /r \\ + 05 \raRaArgH\byteWidthH & mov byte [/r], [/r] & [/r] & [/r] \\ + 05 \raRaArgH\shortWidthH & mov short [/r], [/r] & [/r] & [/r] \\ + 05 \raRaArgH\intWidthH & mov (int) [/r], [/r] & [/r] & [/r] \\ + 05 \raAArgH\byteWidthH & mov byte [/r], [imm32] & [/r] & [imm32] \\ + 05 \raAArgH\shortWidthH & mov short [/r], [imm32] & [/r] & [imm32] \\ + 05 \raAArgH\intWidthH & mov (int) [/r], [imm32] & [/r] & [imm32] \\ + + 05 \immRArgH\byteWidthH & mov byte imm8, /r & imm8 & /r \\ + 05 \immRArgH\shortWidthH & mov short imm16, /r & imm16 & /r \\ + 05 \immRArgH\intWidthH & mov (int) imm32, /r & imm32 & /r \\ + 05 \immRaArgH\byteWidthH & mov byte imm8, [/r] & imm8 & [/r] \\ + 05 \immRaArgH\shortWidthH & mov short imm16, [/r] & imm16 & [/r] \\ + 05 \immRaArgH\intWidthH & mov (int) imm32, [/r] & imm32 & [/r] \\ + 05 \immAArgH\byteWidthH & mov byte imm8, [imm32] & imm8 & [imm32] \\ + 05 \immAArgH\shortWidthH & mov short imm16, [imm32] & imm16 & [imm32] \\ + 05 \immAArgH\intWidthH & mov (int) imm32, [imm32] & imm32 & [imm32] \\ + + 05 \aRArgH\byteWidthH & mov byte [imm32], /r & [imm32] & /r \\ + 05 \aRArgH\shortWidthH & mov short [imm32], /r & [imm32] & /r \\ + 05 \aRArgH\intWidthH & mov (int) [imm32], /r & [imm32] & /r \\ + 05 \aRaArgH\byteWidthH & mov byte [imm32], [/r] & [imm32] & [/r] \\ + 05 \aRaArgH\shortWidthH & mov short [imm32], [/r] & [imm32] & [/r] \\ + 05 \aRaArgH\intWidthH & mov (int) [imm32], [/r] & [imm32] & [/r] \\ + 05 \aAArgH\byteWidthH & mov byte [imm32], [imm32] & [imm32] & [imm32] \\ + 05 \aAArgH\shortWidthH & mov short [imm32], [imm32] & [imm32] & [imm32] \\ + 05 \aAArgH\intWidthH & mov (int) [imm32], [imm32] & [imm32] & [imm32] \\ \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}.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 06 \rRArgH\byteWidthH & and byte /r, /r & /r & /r \\ + 06 \rRArgH\shortWidthH & and short /r, /r & /r & /r \\ + 06 \rRArgH\intWidthH & and (int) /r, /r & /r & /r \\ + 06 \immRArgH\byteWidthH & and byte /imm8, /r & /imm8 & /r \\ + 06 \immRArgH\shortWidthH & and short /imm16, /r & /imm16 & /r \\ + 06 \immRArgH\intWidthH & and (int) /imm32, /r & /imm32 & /r \\ + \hline + \end{tabularx} + \paragraph{Description} Bitwise AND's the source (operand one) with the destination (operand two) storing the result in the destination. If the result of the operation is zero then the Zero Flag (ZF) is set. + \paragraph{Flags Affected} ZF. \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}.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 07 \rRArgH\byteWidthH & or byte /r, /r & /r & /r \\ + 07 \rRArgH\shortWidthH & or short /r, /r & /r & /r \\ + 07 \rRArgH\intWidthH & or (int) /r, /r & /r & /r \\ + 07 \immRArgH\byteWidthH & or byte /imm8, /r & /imm8 & /r \\ + 07 \immRArgH\shortWidthH & or short /imm16, /r & /imm16 & /r \\ + 07 \immRArgH\intWidthH & or (int) /imm32, /r & /imm32 & /r \\ + \hline + \end{tabularx} + \paragraph{Description} Bitwise OR's the source (operand one) with the destination (operand two) storing the result in the destination. If the result of the operation is zero then the Zero Flag (ZF) is set. + \paragraph{Flags Affected} ZF. \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}.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 08 \rRArgH\byteWidthH & xor byte /r, /r & /r & /r \\ + 08 \rRArgH\shortWidthH & xor short /r, /r & /r & /r \\ + 08 \rRArgH\intWidthH & xor (int) /r, /r & /r & /r \\ + 08 \immRArgH\byteWidthH & xor byte /imm8, /r & /imm8 & /r \\ + 08 \immRArgH\shortWidthH & xor short /imm16, /r & /imm16 & /r \\ + 08 \immRArgH\intWidthH & xor (int) /imm32, /r & /imm32 & /r \\ + \hline + \end{tabularx} + \paragraph{Description} Bitwise exclusive OR's (XOR) the source (operand one) with the destination (operand two) storing the result in the destination. If the result of the operation is zero then the Zero Flag (ZF) is set. + \paragraph{Flags Affected} ZF. \subsection{NOT} -\OpcodeTable{01 /r}{not /r}{Register}{None}{Bit-wise negates \textit{Operand 1} placing the result into \textit{Operand 1}.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 09 & xor /r & /r & None \\ + \hline + \end{tabularx} + \paragraph{Description} Bit-wise NOT's the source (operand one) in place. + \paragraph{Flags Affected} None. \subsection{SHL} -\OpcodeTable{01 /r /i8}{shl /r, /i8}{Register}{Immediate}{Shifts the bits of \textit{Operand 1} left \textit{Operand 2} times.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 0A \immRArgH\byteWidthH & shl byte imm8, /r & imm8 & /r \\ + 0A \immRArgH\shortWidthH & shl short imm16, /r & imm16 & /r \\ + 0A \immRArgH\intWidthH & shl (int) imm32, /r & imm32 & /r \\ + \hline + \end{tabularx} + \paragraph{Description} Shifts the destination (operand two) left \textit{operand one} times in place. If the source is smaller than before the operation the overflow flag (OF) is set. If the result of the operation is zero than the zero flag (ZF) is set. + \paragraph{Flags Affected} OF and ZF. \subsection{SHR} -\OpcodeTable{01 /r /i8}{shr /r, /i8}{Register}{Immediate}{Shifts the bits of \textit{Operand 1} right \textit{Operand 2} times.} - + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 0B \immRArgH\byteWidthH & shr byte imm8, /r & imm8 & /r \\ + 0B \immRArgH\shortWidthH & shr short imm16, /r & imm16 & /r \\ + 0B \immRArgH\intWidthH & shr (int) imm32, /r & imm32 & /r \\ + \hline + \end{tabularx} + \paragraph{Description} Shifts the destination (operand two) right \textit{operand one} times in place. If the source is larger than before the operation the underflow flag (UF) is set. If the result of the operation is zero than the zero flag (ZF) is set. + \paragraph{Flags Affected} UF and ZF. \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. + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 0C & nop & None & None \\ + \hline + \end{tabularx} + \paragraph{Description} Performs no operation except for incrementing the program counter by one. + \paragraph{Flags Affected} None. \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.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 0D \rRArgH\intWidthH & cmp /r, /r & /r & /r \\ + \hline + \end{tabularx} + \paragraph{Description} Compares \textit{operand one} to \textit{operand two} by subtracting \textit{operand one} from \textit{operand two}, updating the status register with the results. If \textit{operand one} is larger than the result, and the result is not zero, the overflow flag (OF) is set. If \textit{operand one} is smaller than the result, and the result is not zero, the underflow flag (UF) is set. And if the result of the subtraction is zero the zero flag (ZF) is set. + \paragraph{Flags Affected} OF, UF and ZF. \subsection{JMP} -\OpcodeTable{01 /mod /i32}{jmp /i32}{Immediate}{None}{Unconditionally jumps to address \textit{Operand 1}.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 0E & jmp /imm32 & /imm32 & None \\ + \hline + \end{tabularx} + \paragraph{Description} Jumps unconditionally to the absolute memory address specified in \textit{operand one}. + \paragraph{Flags Affected} None. \subsection{JZ} -\OpcodeTable{01 /i32}{jz /i32}{Immediate}{None}{Jumps to address \textit{Operand 1} if the Zero Flag is set.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 0F & jz /imm32 & /imm32 & None \\ + \hline + \end{tabularx} + \paragraph{Description} Jumps to the absolute memory address specified in \textit{operand one} if the zero flag (ZF) is zet. + \paragraph{Flags Affected} None. \subsection{JG} -\OpcodeTable{01 /mod /i32}{jg /i32}{Immediate}{None}{Jumps to address \textit{Operand 1} if the Sign Flag is set.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 10 & jg /imm32 & /imm32 & None \\ + \hline + \end{tabularx} + \paragraph{Description} Jumps to the absolute memory address specified in \textit{operand one} if the overflow flag (OF) is zet. + \paragraph{Flags Affected} None. \subsection{JL} -\OpcodeTable{01 /mod /i32}{jl /i32}{Immediate}{None}{Jumps to address \textit{Operand 1} if the Sign Flag is not set.} - + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 11 & jl /imm32 & /imm32 & None \\ + \hline + \end{tabularx} + \paragraph{Description} Jumps to the absolute memory address specified in \textit{operand one} if the underflow flag (UF) is zet. + \paragraph{Flags Affected} None. %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}.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 12 & outb /imm8, /imm8 & /imm8 & /imm8 \\ + \hline + \end{tabularx} + \paragraph{Description} Writes a byte of data to the port number specified in the destination (operand two). + \paragraph{Flags Affected} None. \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}.} - + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 13 & inb /imm8, /r & /imm8 & /r \\ + \hline + \end{tabularx} + \paragraph{Description} Reads a byte of data from the port number in source (operand one) to the destination (operand two) register. + \paragraph{Flags Affected} None. \subsection{HLT} -\OpcodeTable{01}{hlt}{None}{None}{Halts the processor until a new interrupt is received.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 14 & hlt & None & None \\ + \hline + \end{tabularx} + \paragraph{Description} Halts the processor preventing it from executing the next instruction until an interrupt is received. + \paragraph{Flags Affected} None. \subsection{CLI}\label{sec:cli} -\OpcodeTable{01}{cli}{None}{None}{Clears the interrupt flag preventing the processor from receiving interrupts.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 15 & cli & None & None \\ + \hline + \end{tabularx} + \paragraph{Description} Clears interrupts, preventing the processor from responding to interrupts. + \paragraph{Flags Affected} None. \subsection{ENI}\label{sec:eni} -\OpcodeTable{01}{eni}{None}{None}{Sets the interrupt flag allowing the processor to receive interrupts.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 16 & eni & None & None \\ + \hline + \end{tabularx} + \paragraph{Description} Enables interrupts, allowing the processor to respond to interrupts. + \paragraph{Flags Affected} None. \subsection{INT}\label{sec:int} -\OpcodeTable{01 /i8}{int /i8}{Immediate}{None}{Triggers software interrupt number \textit{Operand 1}.} + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 17 & int /imm8 & /imm8 & None \\ + \hline + \end{tabularx} + \paragraph{Description} Triggers a software interrupt of type \textit{operand one} causing the flow of execution to jump to the registered subroutine in the Interrupt Vector Table at index \textit{operand one}. + \paragraph{Flags Affected} None. \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}.} \ No newline at end of file + \begin{tabularx}{\textwidth}{ | c | X | c | c | } + \hline + Opcode & Instruction & Operand One & Operand Two \\ + \hline + 18 & livt /imm32 & /imm32 & None \\ + \hline + \end{tabularx} + \paragraph{Description} Registers a 1024 byte block of memory starting at \textit{operand one} as the Interrupt Vector Table. + \paragraph{Flags Affected} None. \ No newline at end of file