[CD] x86 lite summary

This commit is contained in:
janishutz committed 2026-09-25 15:28:20 +02:00
1 parent 7b2517e453
commit 01f455e991
9 files changed
+136 -3

No files matched your search

Binary file not shown.
+5
View File
@@ -9,6 +9,7 @@
\begin{document}
\startDocument
\summaryspacing
\vspace{1cm}
\begin{center}
@@ -41,6 +42,10 @@
\section{Introduction}
This summary is still a very early version and structure and content will still change and errors will be fixed.
It is also likely that it won't be as extensive and detailed as some of my others due to the more applied nature of the course
and the fact that a Cheat Sheet can be brought to the exam.
\newpage
\input{parts/main.tex}
@@ -0,0 +1,30 @@
\subsection{Introduction}
x86lite is a subset of the full x86 ISA, with only about 20 instructions and only 64-bit signed integers, nothing else.
It is further interoperable with x86.
As a quick reminder, the following registers are relevant for x86lite:
\begin{multicols}{4}
\begin{itemize}
\item \texttt{rax}
\item \texttt{rbx}
\item \texttt{rcx}
\item \texttt{rdx}
\item \texttt{rsi}
\item \texttt{rdi}
\item \texttt{rbp} (Base Pointer)
\item \texttt{rsp} (Stack Pointer)
\item \texttt{r08}
\item \texttt{r09}
\item \texttt{r10}
\item \texttt{r11}
\item \texttt{r12}
\item \texttt{r13}
\item \texttt{r14}
\item \texttt{r16}
\end{itemize}
\end{multicols}
Further, the \texttt{rip} points to the next instruction. Then, the CPU has processor state registers, such as \texttt{OF} (set, if the last instruction caused an overflow),
\texttt{ZF} (set if last result was zero), etc.
On x86, the heap grows upwards, the stack grows downwards, where the code and data section that precedes the heap in the address space contains program code, constants and globals.
@@ -0,0 +1,14 @@
\subsection{Instructions \& Syntax}
x86lite uses the AT\&T syntax, where the source comes \textit{before} the destination, immediates are prefixed with a \texttt{\$} and registers with a \texttt{\%}.
Each mnemonic has suffixes \texttt{q = quadword} (4 words), \texttt{l = long} (2 words), \texttt{w = word} (16 bits) and \texttt{b = byte} (8 bit),
for example \texttt{movq \$5, \%rax}. This syntax is prevalent in the UNIX ecosystem {\scriptsize (thus is \textit{objectively} superior\dots)}
The following operands can be passed to instructions:
\begin{itemize}
\item \bi{Immediate} (\texttt{Imm}):
\item \bi{Label} (\texttt{Lbl}):
\item \bi{Register} (\texttt{Reg}):
\item \bi{Machine Address} (\texttt{Ind}): Using the format \texttt{disp(base, index, scale)}, with the address computed as \texttt{disp + base + index * scale},
with \texttt{base} and \texttt{index} registers (\texttt{index} cannot be the \texttt{rsp} reg) and \texttt{disp} and \texttt{scale} \texttt{int32} immediates,
where in x86lite \texttt{scale} is by default \texttt{8}
\end{itemize}
@@ -0,0 +1,68 @@
\subsection{List of instructions}
A list of instructions is also provided on the Moodle page for the course.
\subsubsection{Arithmetic Instructions}
\begin{tables}{lll}{Instruction & Explanation & Example}
\texttt{negq DEST} & 2's complement negation & \verb|negq %rax| \\
\texttt{addq SRC, DEST} & $\text{DEST} \gets \text{DEST} + \text{DEST}$ & \verb|addq %rbx, %rax| \\
\texttt{subq SRC, DEST} & $\text{DEST} \gets \text{DEST} + \text{DEST}$ & \verb|subq $4, %rsp| \\
\texttt{imulq SRC, DEST} & $\text{DEST} \gets \text{DEST} \times \text{DEST}$ & \verb|imulq $4, %rax| \\
\end{tables}
\subsubsection{Logic/Bit Manipulation Instructions}
\begin{tables}{lll}{Instruction & Explanation & Example}
\texttt{notq DEST} & bitwise not & \verb|notq %rax| \\
\texttt{andq SRC, DEST} & $\text{DEST} \gets \text{DEST}\ \&\ \text{DEST}$ & \verb|andq %rbx, %rax| \\
\texttt{orq SRC, DEST} & $\text{DEST} \gets \text{DEST}\ |\ \text{DEST}$ & \verb|orq $4, %rsp| \\
\texttt{xorq SRC, DEST} & $\text{DEST} \gets \text{DEST}\ \texttt{xor}\ \text{DEST}$ & \verb|xorq $2, %rax| \\
\texttt{sarq Amt, DEST} & $\text{DEST} \gets \text{DEST} \gg \text{Amt}$ (Arithmetic right shift) & \verb|sarq $4, %rax| \\
\texttt{shrq Amt, DEST} & $\text{DEST} \gets \text{DEST} \ggg \text{Amt}$ (Logical right shift) & \verb|shrq $1, %rsp| \\
\texttt{shlq Amt, DEST} & $\text{DEST} \gets \text{DEST} \lll \text{Amt}$ (Logical left shift) & \verb|shlq %rbx, %rax| \\
\end{tables}
\subsubsection{Control Flow, Blocks and Labels}
As you are probably aware of, x86 assembly organizes code into \textit{labeled blocks}.
Labels are translated away by the linker and loader and the code begins executing at a designated code label (usually ``main'').
To call a subroutine at a given label, we can use the \texttt{call LABEL} instruction and we can use the \texttt{ret} instruction to return from the procedure.
\begin{tables}{lll}{Instruction & Description & Notes}
\texttt{jmp SRC} & $\texttt{rip} \gets \texttt{SRC}$ & Jump to location in \texttt{SRC} \\
\texttt{call SRC} & Push \texttt{rip}; $\texttt{rip} \gets \texttt{SRC}$ & Push program counter (\texttt{rip}) onto stack, decrement \texttt{rsp} \\
\texttt{ret} & Pop into \texttt{rip} & Pop top of stack into \texttt{rip}, increment \texttt{rsp} \\
\end{tables}
This means that the \texttt{call} and \texttt{ret} instructions act like some sort of abstraction of \texttt{jmp}.
\subsubsection{Condition Flags \& Codes, Conditional Instructions}
The following flags are set as side effects from normal instructions:
\begin{itemize}
\item \texttt{OF} \textit{overflow}: is set when the result is too big or small to fit in the 64 bit register
\item \texttt{SF} \textit{sign}: set to the sign of the result
\item \texttt{ZF} \textit{zero}: set when the result is 0
\end{itemize}
From these flags, we can define \textit{condition codes}:
\begin{tables}{lll}{Condition Codes & Condition & Description}
\texttt{e} & \verb|ZF| & Equal / Zero \\
\texttt{ne} & \verb+~ZF+ & Not Equal / Not Zero \\
\texttt{g} & \verb+~(SF^OF)&~ZF+ & Greater (signed) \\
\texttt{ge} & \verb+~(SF^OF)+ & Greater or equal (signed) \\
\texttt{l} & \verb+SF^OF+ & Less (signed) \\
\texttt{le} & \verb+(SF^OF)|ZF+ & Less or equal (signed) \\
\end{tables}
Instead of manually computing \texttt{SRC1 - SRC2} manually, we can instead use the following instructions to set the condition codes:
\begin{tables}{ll}{Instruction & Description }
\texttt{cmpq SRC2, SRC1} & Computes \texttt{SRC1 - SRC2} sets condition flags \\
\texttt{setb CC, DEST} & \texttt{DEST}'s lower byte $\gets$ if \texttt{CC} then 1 else 0 \\
\texttt{jCC SRC} & \texttt{rip} $\gets$ if \texttt{CC} then \texttt{SRC} else fall through \\
\end{tables}
\subsubsection{Stack Operations \& Memory Model}
To load a pointer into a register, we can use \texttt{leaq Ind, DEST}, which does $\texttt{DEST} \gets \texttt{addr(Ind)}$.
As mentioned previously, the x86 stack grows downwards, so the \texttt{pushq SRC} instruction computes $\texttt{rsp} \gets \texttt{rsp} - 8; \texttt{Mem[rsp]} \gets \texttt{SRC}$,
where \texttt{popq DEST} computes $\texttt{DEST} \gets \texttt{Mem[rsp];} \texttt{rsp} \gets \texttt{rsp} + 8$.
@@ -0,0 +1,15 @@
\subsection{Calling Conventions}
As covered in SPCA, the stack in \texttt{C} stores local variables and other book-keeping data.
Global variables are stored in the code and data section at the low end of the address space.
Further, remember that the \texttt{rbp} (base pointer) register by convention contains the \textit{previous value} of \texttt{rsp}.
\subsubsection{Callee vs Caller Saved registers}
By convention, the registers \texttt{rbp, rsp, rbx, r12, r13, r14, r15} are \textit{Callee-Saved}, i.e. it is the duty of the \textit{subroutine} (the callee) to restore them.
All other registers are \textit{Caller-Saved}, meaning that the callee can freely use them.
\subsubsection{Arguments}
Function arguments one through six are stored in \texttt{rdi, rsi, rdx, rcx, r8, r9}, respectively, any extra arguments are to be stored on the stack in right-to-left order,
meaning that for $n > 6$, the $n$-th argument is at $((n - 7) + 2) * 8 + \texttt{rbp}$.
The return value is stored in \texttt{rax} and the stack must be 16-byte aligned on a call.
Further, there is a 128 byte ``red zone'', which is a scratch pad for the callee's data, which is there for optimization.
+4 -1
View File
@@ -1,7 +1,10 @@
\section{OCAML}
\input{parts/ocaml/main.tex}
\input{parts/00_ocaml/00_basics.tex}
\section{x86Lite}
\input{parts/01_x86-lite/00_intro.tex}
\input{parts/01_x86-lite/01_instructions.tex}
\input{parts/01_x86-lite/02_instruction-list.tex}
\section{LLVM}
-2
View File
@@ -1,2 +0,0 @@
\subsection{The basics}
\input{parts/ocaml/00_basics.tex}