Files
lang/chapter 1.tex
T

121 lines
7.7 KiB
TeX

\chapter{Introduction}
This is an attempt to distill what I know about how computers work into some kind of emulator / simulator. I'm curious to see if what I know at the moment is enough to allow me too emulate a general purpose computer. It turns out that it take quite a different skill set compared to writing web or desktop applications. But I realize that, while I understand the concepts that underpin what I do day to day, I don't have an intuitive understanding of the hardware. This has become painfully evident pretty much immediately after I started this project. An ISA should be simple, add, subtract, copy, etc., but then you have to consider the state that the processor will be in after each instruction.
\section{Conventions \& Data Types}
This machine is \quotes{little endian} meaning bytes are numbered starting from the least significant byte or the right most byte. Figure \ref{fig:bytelayout} shows how a structure is layed out in memory byte by byte.
\begin{figure}[h]
\begin{tikzpicture}
% Row 0
\node [draw, fit={( 0.0, 0.0) ( 2.0, 0.5)}, inner sep=0, label=center:byte 0] (row0b0) {};
\node [draw, fit={( 0.0, 0.0) (-2.0, 0.5)}, inner sep=0, label=center:byte 1] (row0b1) {};
\node [draw, fit={(-2.0, 0.0) (-4.0, 0.5)}, inner sep=0, label=center:byte 2] (row0b2) {};
\node [draw, fit={(-4.0, 0.0) (-6.0, 0.5)}, inner sep=0, label=center:byte 3] (row0b3) {};
% Row 1
\node [draw, fit={( 0.0, 0.5) (2.0, 1.0)}, inner sep=0] (row1b0) {};
\node [draw, fit={( 0.0, 0.5) (-2.0, 1.0)}, inner sep=0] (row1b1) {};
\node [draw, fit={(-2.0, 0.5) (-4.0, 1.0)}, inner sep=0] (row1b2) {};
\node [draw, fit={(-4.0, 0.5) (-6.0, 1.0)}, inner sep=0] (row1b3) {};
% Row 2
\node [draw, fit={( 0.0, 1.0) ( 2.0, 1.5)}, inner sep=0] (row2b0) {};
\node [draw, fit={( 0.0, 1.0) (-2.0, 1.5)}, inner sep=0] (row2b1) {};
\node [draw, fit={(-2.0, 1.0) (-4.0, 1.5)}, inner sep=0] (row2b2) {};
\node [draw, fit={(-4.0, 1.0) (-6.0, 1.5)}, inner sep=0] (row2b3) {};
% Draw Row 0 Byte Offset
\node at (row0b0.east)[right] (offset) {0};
\node at (offset.south)[below] {Byte Offset};
%Draw Row 1 byte offset
\node at (row1b0.east)[right] {4};
%Draw Row 2 bit offset label and bit positions
\node at (row2b0.east)[right] {8}; % Byte offset
\node at (row2b0.north east)[above] {0};
\node at (row2b0.north west)[above] {8 7};
%
\node at (row2b1.north west)[above] {16 15};
%
\node at (row2b2.north west)[above] {24 23};
%
\node at (row2b3.north west)[above] (mostbit) {31};
\node at (mostbit.west)[left] {Bit Offset};
\end{tikzpicture}
\caption{Layout of a Structure in Memory}
\label{fig:bytelayout}
\end{figure}
There are three data types that are understood by this machine: byte, short and word.
\begin{description}
\item[Byte] An octet or a structure that is exactly 8-bits wide.
\item[Short] To loosely borrow from C, a short is exactly two bytes or 16-bits wide.
\item[Word] Exactly four bytes wide, or 32-bits.
\end{description}
\section{Registers}
Thirty-two general purpose registers are available for program code to use however it wishes. The base name for the general purpose registers is \quotes{r} follows by an unpadded number, such as \quotes{r8}. These numbers do not follow a zero-based index scheme, \quotes{r29} is the twenty-ninth register. Using the base name implies full width, a \quotes{word}, when reading or writing from or to the register respectively.
In addition to the general purpose registers there is also a base pointer (bp), stack pointer (sp) and an instruction pointer (ip). The base pointer and the stack pointer may be set directly using the \hyperref[sec:mov]{mov} instruction, which allows the programmer to set up a stack frame. The instruction pointer can only be set with a branching operation like \hyperref[sec:jmp]{jmp} or a call to a subroutine with the \hyperref[sec:call]{call} instruction. One final register that can only be indirectly set is the \quotes{flags} register. This register, like the others, is one word wide meaning it can store thirty-two flags. Currently only three flags are present, the Zero, Underflow and Overflow flags. These flags are only affected by arithmetic operations and generally read by branching instructions like \hyperref[sec:jmp]{jmp}.
\begin{figure}[h]
\begin{tikzpicture}
%\draw[help lines] (-8,-3) grid (8,3);
\node [draw, fit={(-6, 0) (-1, -0.5)}, label=center:r1] (r1) {};
\node [draw=none, fit={(-6, -1) (-1, -1.5)}, label=center:...] (ellipsis) {};
\node [draw, fit={(-6, -2) (-1, -2.5)}, label=center:r32] (r32) {};
\node [draw, fit={(-3.0, 1.5) (2.0, 1.0)}, label=center:Flags Register] (flags) {};
\node [draw, fit={(0, 0) (5, -0.5)}, label=center:Instruction Pointer (ip)] (ip) {};
\node [draw, fit={(0, -1.0) (5, -1.5)}, label=center:Base Pointer (ip)] (bp) {};
\node [draw, fit={(0, -2.0) (5, -2.5)}, label=center:Stack Pointer (ip)] (sp) {};
\draw (r1);
\node at (r1.north) [above] {General Purpose};
\node at (r1.north west) [above] {31};
\node at (r1.north east) [above] {0};
\draw (ellipsis);
\draw (r32);
\draw (flags);
\node at (flags.north) [above] {Status Register};
\node at (flags.north west) [above] {31};
\node at (flags.north east) [above] {0};
\draw (ip);
\node at (ip.north) [above] {Program Status};
\node at (ip.north west) [above] {31};
\node at (ip.north east) [above] {0};
\draw (bp);
\draw (sp);
\end{tikzpicture}
\caption{Bit Ordering}
\label{fig:registerbitlayout} % https://www.overleaf.com/learn/latex/Referencing_Figures
\end{figure}
\begin{description}
\item In summary, the available registers are as follows:
\item[General Purpose] Thirty-two general purpose registers that are the width of a \textit{word} and numbered \quotes{r1} through \quotes{r32}
\item[Base Pointer (bp)] Points to the call location when a function call is made
\item[Stack Pointer (sp)] points to the end of the last argument after a function call is executed, which may be the return address of the stack
\item[Instruction Pointer (ip)] Points to the next instruction to execute and advanced by the width of an instruction. Set by jump or call instructions to the location specified by the instruction.
\end{description}
\section{Memory}
The memory layout is quite simple, much like many modern machines it is a linear memory map. The address bus is thirty-two bits wide, the same width of the data bus, meaning at most there is 2\textsuperscript{32} of addressable memory. Like contemporary machines the top of memory starts at address 0x00000000 and grows downward toward 0xFFFFFFFF. By default the memory is mapped as shown in Figure \ref{fig:memorylayout}.
% How memory mapped I/O works: https://superuser.com/questions/595672/how-is-memory-mapped-to-certain-hardware-how-is-mmio-accomplished-exactly
\begin{figure}
\begin{tikzpicture}
\node [draw, fit={(0,0) (3, 6)}] (memory) {};
\draw (memory);
\node (top) at (memory.north east)[right] {0x00000000};
\node at (memory.south east)[right] {0xFFFFFFFF};
\draw[->] ($(memory.west)-(0.5,-0.25)$)[left] -- ($(memory.north west)-(0.5,0.0)$)[left] node[midway, left] {Stack};
\draw[->] ($(memory.west)-(0.5, 0.25)$)[left] -- ($(memory.south west)-(0.5,0.0)$)[above] node[midway, left] {Heap};
%\draw[dashed] ($(memory.north west)-(0.0,0.5)$) node[left] {0x000800} -- ($(memory.north east)-(0.0,0.5)$) node[midway, above] {IVT - 2kb};
%\draw[dashed] ($(memory.north west)-(0.0,1.0)$) -- ($(memory.north east)-(0.0,1.0)$) node[right] {0x200800} node[midway, above] {Firmware - 2MiB};
%\draw[dashed] ($(memory.north west)-(0.0,1.5)$) node[left] {0x276100} -- ($(memory.north east)-(0.0,1.5)$) node[midway, above] {VRAM - 3.75MiB};
\end{tikzpicture}
\caption{Memory Map \& Layout}
\label{fig:memorylayout} % https://www.overleaf.com/learn/latex/Referencing_Figures
\end{figure}