mirror of
https://github.com/janishutz/eth-summaries.git
synced 2026-10-09 05:46:20 +02:00
[CD] x86 lite summary
This commit is contained in:
1 parent
7b2517e453
commit
01f455e991
9 files changed
+136
-3
No files matched your search
Binary file not shown.
@@ -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}
|
||||
|
||||
|
||||
File renamed without changes.
@@ -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.
|
||||
@@ -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}
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
\subsection{The basics}
|
||||
\input{parts/ocaml/00_basics.tex}
|
||||
Reference in new issue
Block a user