mirror of
https://github.com/janishutz/eth-summaries.git
synced 2026-01-13 08:48:25 +00:00
[SPCA] Finish stack, data type compilation details
This commit is contained in:
@@ -1,61 +0,0 @@
|
||||
\newpage
|
||||
\subsection{The syntax}
|
||||
There are two common styles: AT\&T syntax (common on UNIX) and Intel syntax (common on Windows)
|
||||
|
||||
The state that is visible to us is:
|
||||
\begin{itemize}
|
||||
\item PC (Program Counter) that contains the address of the next instruction
|
||||
\item Register file that contains the most used program data
|
||||
\item Condition codes that store status information about most recent arithmetic operation and are used for conditional branching
|
||||
\end{itemize}
|
||||
|
||||
To view what \lC\ code looks like in assembly, we can use \texttt{gcc -O0 -S code.c}, which produces \texttt{code.s} which contains assembly code.
|
||||
|
||||
\subsubsection{Registers}
|
||||
\texttt{x86} assembly is a bit particular with register naming (register names all start in \%).
|
||||
The initial 16-bit version of \texttt{x86} had the following registers (sub registers are registers that can be used to access the high
|
||||
(\texttt{h} suffix) or low (\texttt{l} suffix) half of the register. Only registers ending in \texttt{x} feature these sub registers.
|
||||
They, as well as \texttt{\%si} and \texttt{\%di} are general purpose):
|
||||
\begin{tables}{lll}{Name & Sub-registers & Description}
|
||||
\texttt{\%ax} & \texttt{\%ah}, \texttt{\%al} & accumulate \\
|
||||
\texttt{\%cx} & \texttt{\%ch}, \texttt{\%cl} & counter \\
|
||||
\texttt{\%dx} & \texttt{\%dh}, \texttt{\%dl} & data \\
|
||||
\texttt{\%bx} & \texttt{\%bh}, \texttt{\%bl} & base \\
|
||||
\texttt{\%si} & - & Source index \\
|
||||
\texttt{\%di} & - & Destination index \\
|
||||
\hline
|
||||
\texttt{\%sp} & - & Stack pointer \\
|
||||
\texttt{\%bp} & - & Base pointer \\
|
||||
\texttt{\%ip} & - & Instruction pointer \\
|
||||
\texttt{\%sr} & - & Status (flags) \\
|
||||
\end{tables}
|
||||
When the architecture was extended to 32-bit, all registers previously available were retained and a 32 bit version of each was introduced with the prefix \texttt{e}.
|
||||
In other words, any 16 bit code would still work as previously, as e.g. the \texttt{\%ax} register was simply now the lower 16 bits of the \texttt{\%eax} register.
|
||||
|
||||
The same happened again when extending to 64-bit, only this time the \texttt{r} prefix was used.
|
||||
So, the register \texttt{\$eax} was now the lower 32 bits of \texttt{\%rax}.
|
||||
|
||||
Additionally, the following registers are also available, with \texttt{X} to be substituted with 8 through 15: \texttt{\%rX} and the lower 32 bits \texttt{\%rXd}
|
||||
|
||||
\subsubsection{Instructions}
|
||||
Instructions usually have a 3 letter \texttt{mnemonic} with a one letter postfix that indicates the number of bytes.
|
||||
The following postfixes are available: \texttt{b} (byte, 1 byte), \texttt{w} (word, 2 bytes), \texttt{l} (long word, 4 bytes) and \texttt{q} (quad, 8 bytes).
|
||||
|
||||
The following options can be passed for source and destination: Registers,
|
||||
|
||||
\content{Immediates} To use a constant value (aka Immediate) in an instruction, we prefix the number with \texttt{\$} (following number is decimal).
|
||||
To use hex, we can use \texttt{\$0x}, etc.
|
||||
|
||||
\content{Memory addresses} To treat a register as a memory address, use parenthesis, e.g. \texttt{(\%rax)} interprets the value of \texttt{\%rax} as a memory address.
|
||||
The instruction will then read the number of bytes, as specified by the postfix of the instruction.
|
||||
|
||||
The full syntax for memory address modes is \texttt{D(Rb, Ri, S)}, where
|
||||
\begin{itemize}[noitemsep]
|
||||
\item \texttt{D}: Displacement (constant offset), can be 0, 1, 2 or 4 bytes (not bits, if you are confused as I was)
|
||||
\item \texttt{Rb}: Base register (to which offsets, etc are added). Can be any of the 16 integer registers
|
||||
\item \texttt{Ri}: Index register: Any, except for \texttt{\%rsp} (and \texttt{\%rbp} is also rarely used)
|
||||
\item \texttt{S}: Scale factor (1, 2, 4 or 8, to correct offsets)
|
||||
\end{itemize}
|
||||
The computation that happens is the following: \texttt{Mem[ Reg[Rb] + S * Reg[Ri] + D ]}.
|
||||
Using the \texttt{lea src, dest} instruction, we can get the address computed into the dest register.
|
||||
Can be abused for similar arithmetic expressions.
|
||||
12
semester3/spca/parts/00_asm/01_syntax/00_intro.tex
Normal file
12
semester3/spca/parts/00_asm/01_syntax/00_intro.tex
Normal file
@@ -0,0 +1,12 @@
|
||||
\newpage
|
||||
\subsection{The syntax}
|
||||
There are two common styles: AT\&T syntax (common on UNIX) and Intel syntax (common on Windows)
|
||||
|
||||
The state that is visible to us is:
|
||||
\begin{itemize}
|
||||
\item PC (Program Counter) that contains the address of the next instruction
|
||||
\item Register file that contains the most used program data
|
||||
\item Condition codes that store status information about most recent arithmetic operation and are used for conditional branching
|
||||
\end{itemize}
|
||||
|
||||
To view what \lC\ code looks like in assembly, we can use \texttt{gcc -O0 -S code.c}, which produces \texttt{code.s} which contains assembly code.
|
||||
25
semester3/spca/parts/00_asm/01_syntax/01_registers.tex
Normal file
25
semester3/spca/parts/00_asm/01_syntax/01_registers.tex
Normal file
@@ -0,0 +1,25 @@
|
||||
\subsubsection{Registers}
|
||||
\texttt{x86} assembly is a bit particular with register naming (register names all start in \%).
|
||||
The initial 16-bit version of \texttt{x86} had the following registers (sub registers are registers that can be used to access the high
|
||||
(\texttt{h} suffix) or low (\texttt{l} suffix) half of the register. Only registers ending in \texttt{x} feature these sub registers.
|
||||
They, as well as \texttt{\%si} and \texttt{\%di} are general purpose):
|
||||
\begin{tables}{lll}{Name & Sub-registers & Description}
|
||||
\texttt{\%ax} & \texttt{\%ah}, \texttt{\%al} & accumulate \\
|
||||
\texttt{\%cx} & \texttt{\%ch}, \texttt{\%cl} & counter \\
|
||||
\texttt{\%dx} & \texttt{\%dh}, \texttt{\%dl} & data \\
|
||||
\texttt{\%bx} & \texttt{\%bh}, \texttt{\%bl} & base \\
|
||||
\texttt{\%si} & - & Source index \\
|
||||
\texttt{\%di} & - & Destination index \\
|
||||
\hline
|
||||
\texttt{\%sp} & - & Stack pointer \\
|
||||
\texttt{\%bp} & - & Base pointer \\
|
||||
\texttt{\%ip} & - & Instruction pointer \\
|
||||
\texttt{\%sr} & - & Status (flags) \\
|
||||
\end{tables}
|
||||
When the architecture was extended to 32-bit, all registers previously available were retained and a 32 bit version of each was introduced with the prefix \texttt{e}.
|
||||
In other words, any 16 bit code would still work as previously, as e.g. the \texttt{\%ax} register was simply now the lower 16 bits of the \texttt{\%eax} register.
|
||||
|
||||
The same happened again when extending to 64-bit, only this time the \texttt{r} prefix was used.
|
||||
So, the register \texttt{\$eax} was now the lower 32 bits of \texttt{\%rax}.
|
||||
|
||||
Additionally, the following registers are also available, with \texttt{X} to be substituted with 8 through 15: \texttt{\%rX} and the lower 32 bits \texttt{\%rXd}
|
||||
22
semester3/spca/parts/00_asm/01_syntax/02_instructions.tex
Normal file
22
semester3/spca/parts/00_asm/01_syntax/02_instructions.tex
Normal file
@@ -0,0 +1,22 @@
|
||||
\subsubsection{Instructions}
|
||||
Instructions usually have a 3 letter \texttt{mnemonic} with a one letter postfix that indicates the number of bytes.
|
||||
The following postfixes are available: \texttt{b} (byte, 1 byte), \texttt{w} (word, 2 bytes), \texttt{l} (long word, 4 bytes) and \texttt{q} (quad, 8 bytes).
|
||||
|
||||
The following options can be passed for source and destination: Registers,
|
||||
|
||||
\content{Immediates} To use a constant value (aka Immediate) in an instruction, we prefix the number with \texttt{\$} (following number is decimal).
|
||||
To use hex, we can use \texttt{\$0x}, etc.
|
||||
|
||||
\content{Memory addresses} To treat a register as a memory address, use parenthesis, e.g. \texttt{(\%rax)} interprets the value of \texttt{\%rax} as a memory address.
|
||||
The instruction will then read the number of bytes, as specified by the postfix of the instruction.
|
||||
|
||||
The full syntax for memory address modes is \texttt{D(Rb, Ri, S)}, where
|
||||
\begin{itemize}[noitemsep]
|
||||
\item \texttt{D}: Displacement (constant offset), can be 0, 1, 2 or 4 bytes (not bits, if you are confused as I was)
|
||||
\item \texttt{Rb}: Base register (to which offsets, etc are added). Can be any of the 16 integer registers
|
||||
\item \texttt{Ri}: Index register: Any, except for \texttt{\%rsp} (and \texttt{\%rbp} is also rarely used)
|
||||
\item \texttt{S}: Scale factor (1, 2, 4 or 8, to correct offsets)
|
||||
\end{itemize}
|
||||
The computation that happens is the following: \texttt{Mem[ Reg[Rb] + S * Reg[Ri] + D ]}.
|
||||
Using the \texttt{lea src, dest} instruction, we can get the address computed into the dest register.
|
||||
Can be abused for similar arithmetic expressions.
|
||||
@@ -1,6 +0,0 @@
|
||||
\subsection{Data types}
|
||||
\begin{itemize}
|
||||
\item ``\texttt{Integer}'' data type of 1, 2, 4 or 8 bytes that are data values or addresses (untyped pointers)
|
||||
\item ``\texttt{Floating point}'' data type of 4, 8 or 10 bytes
|
||||
\item No aggregate types (such as arrays, structs, etc)
|
||||
\end{itemize}
|
||||
@@ -0,0 +1,19 @@
|
||||
\subsection{Data types}
|
||||
Assembly supports the following integer types (where GAS stands for GNU Assembly).
|
||||
If they are signed or unsigned does not matter (as we have seen), so it's up to you to interpret them as one or the other
|
||||
\begin{tables}{llll}{Intel & GAS & Bytes & \lC}
|
||||
byte & \texttt{b} & 1 & \texttt{[unsigned] char} \\
|
||||
word & \texttt{w} & 2 & \texttt{[unsigned] short} \\
|
||||
double word & \texttt{l} & 4 & \texttt{[unsigned] int} \\
|
||||
quad word & \texttt{q} & 8 & \texttt{[unsigned] long} \\
|
||||
\end{tables}
|
||||
These integer types are also used for pointer addresses.
|
||||
Assembly also supports floating point numbers.
|
||||
They are stored and operated on in floating point registers.
|
||||
\begin{tables}{llll}{Intel & GAS & Bytes & \lC}
|
||||
single & \texttt{s} & 4 & \texttt{float} \\
|
||||
double & \texttt{l} & 8 & \texttt{double} \\
|
||||
extended & \texttt{t} & 16 & \texttt{long double} \\
|
||||
\end{tables}
|
||||
Assembly does not support any aggregate types (such as arrays, structs, etc) natively.
|
||||
You can however (obviously) make your own. In the following section we will cover how \lC\ datatypes are compiled into assembly.
|
||||
@@ -0,0 +1,7 @@
|
||||
\subsubsection{Arrays}
|
||||
Arrays of type \texttt{T} and length \texttt{L} are allocated as a contiguous region of memory with size \texttt{L * sizeof(T)} bytes.
|
||||
We then also store a reference / identifier \texttt{A} to the array (i.e. similar to variable name in \lC), that holds the address of the first
|
||||
element of the array and can then be used in conjunction with ``assembly pointer arithmetic''.
|
||||
|
||||
Array loops that are written as for-loops in code are usually transformed into do-while loops by the compiler to save one condition check in the beginning,
|
||||
except of course, it might be possible that the loops is never executed.
|
||||
24
semester3/spca/parts/00_asm/02_dtype-dstruct/02_structs.tex
Normal file
24
semester3/spca/parts/00_asm/02_dtype-dstruct/02_structs.tex
Normal file
@@ -0,0 +1,24 @@
|
||||
\subsubsection{Structures}
|
||||
We again allocate a contiguous region of memory.
|
||||
Only now, the number of bytes required isn't as straight forward to compute anymore, it is still not hard:
|
||||
We simply sum up the sizes of all members and that will be our required sizes, so for the $n$ members $x_i$ of struct \texttt{my\_struct}, we have
|
||||
$\texttt{sizeof(my\_struct)} = \sum_{i = 0}^{n - 1} \texttt{sizeof}(x_i)$.
|
||||
|
||||
However, the size of a struct may be different to fulfill alignment requirements set forth by the ISA or operating system.
|
||||
This could mean that the struct takes \texttt{n * K} bytes, where \texttt{K} is the alignment of the largest element
|
||||
|
||||
For alignment on \texttt{x86-64} we have:
|
||||
\mrmvspace
|
||||
\begin{multicols}{2}
|
||||
\begin{itemize}[noitemsep]
|
||||
\item 1 byte (no restrictions)
|
||||
\item 2 bytes (LSB must be 0)
|
||||
\item 4 bytes (2 LSB must be 00)
|
||||
\item 8 bytes (3 LSB must be 000)
|
||||
\item 16 bytes (4 LSB must be 0000)
|
||||
\end{itemize}
|
||||
\end{multicols}
|
||||
|
||||
\dhrmvspace
|
||||
Another issue is accessing members. The solution to this is however easy and efficient, as at compile time, the offsets are pre-determined
|
||||
and compiled into the setter and/or getter code for the struct.
|
||||
@@ -0,0 +1,14 @@
|
||||
\subsubsection{Nested / Multidimensional arrays, Struct arrays}
|
||||
All of these arrays have similar underlying concepts in the way they are allocated, yet all are a bit different
|
||||
|
||||
\content{Common ideas} Each of the array's elements are allocated in contiguous regions of memory, with the elemnts also in contiguous regions of memory.
|
||||
(Imagine it as lining up all elements on a band, i.e. as going through the array in a nested loop and printing all the elements into a single line.)
|
||||
The size of the array is determined by \texttt{n * sizeof(T)}, where \texttt{T} is the type of the elements of the array (or outer array).
|
||||
This is what is different for the lot (as well as accessing elements):
|
||||
|
||||
\content{Nested array} \texttt{T} is another array. We thus have a recursive definition, where \texttt{sizeof(T)} resolves to \texttt{n * sizeof(T1)}, etc.
|
||||
Accessing element $i$, $j$, $k$ is handled as follows: $o = i * \texttt{sizeof(T)} + j * \texttt{sizeof(T1)} + k * \texttt{sizeof(T2)}$,
|
||||
with \texttt{T1} and \texttt{T2} the types of the nested arrays
|
||||
|
||||
\content{Struct arrays} \texttt{T} is a struct.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
\subsubsection{Multi-Level arrays}
|
||||
In comparison to multidimensional arrays, we have arrays of pointers that contain either more arrays of pointers, (normal) arrays or pointers to other data types.
|
||||
The size of such a Multi-Level array is determined by:
|
||||
\texttt{n * sizeof(ptr)}, where \texttt{sizeof(ptr)} is the platform-specific size of a pointer and \texttt{n} is the number of elements in the array
|
||||
|
||||
To do an access, we need to do two (or more) memory reads, which we can again do using address computations.
|
||||
|
||||
The benefit of these kinds of arrays is that we can store arbitrary data types together in an array, giving us more flexibility.
|
||||
@@ -0,0 +1,2 @@
|
||||
\subsubsection{Unions}
|
||||
Since unions can hold any of the elements listed (but only one at a time), we allocate based on the size of the largest element.
|
||||
@@ -1,83 +0,0 @@
|
||||
\subsection{Operations}
|
||||
Assembly operations include performing arithmetic or logic functions on registers or memory data,
|
||||
transferring data between memory and registers and transferring control (conditional or unconditional jumps).\\
|
||||
Note that \verb|move| instructions \textit{cannot} move data directly from memory to memory.
|
||||
|
||||
The following instruction formats are commonly used:
|
||||
|
||||
\inputcodewithfilename{gas}{code-examples/01_asm/}{00_operations.s}
|
||||
|
||||
Arithmetic / logic operations need a size postfix (replace \texttt{X} below with \texttt{b} (1B), \texttt{w} (2B), \texttt{l} (4B) or \texttt{q} (8B)).
|
||||
\begin{tables}{lll}{Mnemonic & Format & Computation}
|
||||
\texttt{addX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest + Src} \\
|
||||
\texttt{subX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest - Src} \\
|
||||
\texttt{imulX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest * Src} \\
|
||||
\texttt{salX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest << Src} \\
|
||||
\texttt{sarX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest >> Src} (arithmetic) \\
|
||||
\texttt{shrX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest >> Src} (logical) \\
|
||||
\texttt{xorX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest \string^ Src} \\
|
||||
\texttt{andX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest \& Src} \\
|
||||
\texttt{orX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest | Src} \\
|
||||
\texttt{incX} & \texttt{Dest} & \texttt{Dest} $\gets$ \texttt{Dest + 1} \\
|
||||
\texttt{decX} & \texttt{Dest} & \texttt{Dest} $\gets$ \texttt{Dest - 1} \\
|
||||
\texttt{negX} & \texttt{Dest} & \texttt{Dest} $\gets$ \texttt{-Dest} \\
|
||||
\texttt{notX} & \texttt{Dest} & \texttt{Dest} $\gets$ \texttt{\string~Dest} \\
|
||||
\end{tables}
|
||||
|
||||
\newpage
|
||||
\subsubsection{Condition Codes}
|
||||
Any arithmetic operation (that is truly part of the arithmetic operations group, so not including \texttt{lea} for example) implicitly sets the \bi{condition codes}.
|
||||
The following condition codes were covered in the lecture (operation: \texttt{t = a + b}):
|
||||
\begin{itemize}
|
||||
\item \texttt{CF} (Carry Flag): Set if carry out from MSB (unsigned overflow)
|
||||
\item \texttt{ZF} (Zero Flag): Set if \texttt{t == 0}
|
||||
\item \texttt{SF} (Sign Flag): Set if \texttt{(a - b) < 0} (for signed)
|
||||
\item \texttt{OF} (Overflow Flag): Set if two's complement overflow (i.e. \verb+(a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0)+)
|
||||
\end{itemize}
|
||||
|
||||
\content{Explicit computation}
|
||||
In the below explanations, we always assume \texttt{src2 = b} and \texttt{src1 = a}
|
||||
|
||||
To explicitly compute them, we can use the \texttt{cmpX src2, src1} instruction (with X again any of the size postfixes),
|
||||
that essentially computes $(a - b)$ without setting a destination register.
|
||||
When we execute that instruction, \texttt{CF} is set if \texttt{a < b} (unsigned), \texttt{ZF} is set if \texttt{a == b}, \texttt{SF} is set if \texttt{a < b} (signed)
|
||||
and \texttt{OF} is set as above, where \texttt{t = a - b}.
|
||||
|
||||
Another instruction that is used is \texttt{testX src2, src1} (X again a size postfix), and acts like computing \texttt{a \& b} and where \texttt{ZF} is set if \texttt{a \& b == 0}
|
||||
and \texttt{SF} is set if \texttt{a \& b < 0}.
|
||||
|
||||
\content{Zeroing register} We can use a move instruction, but that is less efficient than using \texttt{xorl reg, reg}, where \texttt{reg} is the 32-bit version of the reg we want to zero.
|
||||
|
||||
\content{Reading condition codes} To read condition codes, we can use the \texttt{setC} instructions, where the \texttt{C} is to be substituted by an element of table \ref{tab:condition-codes}
|
||||
|
||||
\content{Jumping} To jump, we have the \texttt{jmp <label>} instruction (unconditional jump) or the \texttt{jC} instructions, with \texttt{C} from table \ref{tab:condition-codes}
|
||||
|
||||
\begin{table}[h!]
|
||||
\begin{tables}{lll}{\texttt{setX} & Condition & Description}
|
||||
\texttt{e} & \verb|ZF| & Equal / Zero \\
|
||||
\texttt{ne} & \verb+~ZF+ & Not Equal / Not Zero \\
|
||||
\texttt{s} & \verb|SF| & Negative \\
|
||||
\texttt{ns} & \verb+~SF+ & Nonnegative \\
|
||||
\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) \\
|
||||
\texttt{a} & \verb+~CF&~ZF+ & Above (unsigned) \\
|
||||
\texttt{b} & \verb|CF| & Below (unsigned) \\
|
||||
\end{tables}
|
||||
\caption{Condition code postfixes for jump and set instructions}
|
||||
\label{tab:condition-codes}
|
||||
\end{table}
|
||||
|
||||
\content{Conditional Moves}
|
||||
|
||||
Similar to \texttt{jC}, the same postfixes can be applied to \texttt{cmovC}, for example:
|
||||
|
||||
\begin{minted}{gas}
|
||||
cmpl %eax, %edx
|
||||
cmovle %edx, %eax
|
||||
\end{minted}
|
||||
|
||||
Will move \verb|%edx| into \verb|%eax|, only if \verb|%edx| is less or equal (\verb|le|) \verb|%eax|.
|
||||
|
||||
This can be used to, for example, compile ternary expressions from \verb|C| to Assembly. However, this requires evaluating both possible expressions, which may lead to a (significant) performance overhead.
|
||||
9
semester3/spca/parts/00_asm/03_operations/00_intro.tex
Normal file
9
semester3/spca/parts/00_asm/03_operations/00_intro.tex
Normal file
@@ -0,0 +1,9 @@
|
||||
\newpage
|
||||
\subsection{Operations}
|
||||
Assembly operations include performing arithmetic or logic functions on registers or memory data,
|
||||
transferring data between memory and registers and transferring control (conditional or unconditional jumps).\\
|
||||
Note that \verb|move| instructions \textit{cannot} move data directly from memory to memory.
|
||||
|
||||
The following instruction formats are commonly used:
|
||||
|
||||
\inputcodewithfilename{gas}{code-examples/01_asm/}{00_operations.s}
|
||||
17
semester3/spca/parts/00_asm/03_operations/01_arithmetic.tex
Normal file
17
semester3/spca/parts/00_asm/03_operations/01_arithmetic.tex
Normal file
@@ -0,0 +1,17 @@
|
||||
\subsubsection{Arithmetic Operations}
|
||||
Arithmetic / logic operations need a size postfix (replace \texttt{X} below with \texttt{b} (1B), \texttt{w} (2B), \texttt{l} (4B) or \texttt{q} (8B)).
|
||||
\begin{tables}{lll}{Mnemonic & Format & Computation}
|
||||
\texttt{addX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest + Src} \\
|
||||
\texttt{subX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest - Src} \\
|
||||
\texttt{imulX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest * Src} \\
|
||||
\texttt{salX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest << Src} \\
|
||||
\texttt{sarX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest >> Src} (arithmetic) \\
|
||||
\texttt{shrX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest >> Src} (logical) \\
|
||||
\texttt{xorX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest \string^ Src} \\
|
||||
\texttt{andX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest \& Src} \\
|
||||
\texttt{orX} & \texttt{Src, Dest} & \texttt{Dest} $\gets$ \texttt{Dest | Src} \\
|
||||
\texttt{incX} & \texttt{Dest} & \texttt{Dest} $\gets$ \texttt{Dest + 1} \\
|
||||
\texttt{decX} & \texttt{Dest} & \texttt{Dest} $\gets$ \texttt{Dest - 1} \\
|
||||
\texttt{negX} & \texttt{Dest} & \texttt{Dest} $\gets$ \texttt{-Dest} \\
|
||||
\texttt{notX} & \texttt{Dest} & \texttt{Dest} $\gets$ \texttt{\string~Dest} \\
|
||||
\end{tables}
|
||||
@@ -0,0 +1,24 @@
|
||||
\subsubsection{Condition Codes}
|
||||
Any arithmetic operation (that is truly part of the arithmetic operations group, so not including \texttt{lea} for example) implicitly sets the \bi{condition codes}.
|
||||
The following condition codes were covered in the lecture (operation: \texttt{t = a + b}):
|
||||
\begin{itemize}
|
||||
\item \texttt{CF} (Carry Flag): Set if carry out from MSB (unsigned overflow)
|
||||
\item \texttt{ZF} (Zero Flag): Set if \texttt{t == 0}
|
||||
\item \texttt{SF} (Sign Flag): Set if \texttt{(a - b) < 0} (for signed)
|
||||
\item \texttt{OF} (Overflow Flag): Set if two's complement overflow (i.e. \verb+(a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0)+)
|
||||
\end{itemize}
|
||||
|
||||
\content{Explicit computation}
|
||||
In the below explanations, we always assume \texttt{src2 = b} and \texttt{src1 = a}
|
||||
|
||||
To explicitly compute them, we can use the \texttt{cmpX src2, src1} instruction (with X again any of the size postfixes),
|
||||
that essentially computes $(a - b)$ without setting a destination register.
|
||||
When we execute that instruction, \texttt{CF} is set if \texttt{a < b} (unsigned), \texttt{ZF} is set if \texttt{a == b}, \texttt{SF} is set if \texttt{a < b} (signed)
|
||||
and \texttt{OF} is set as above, where \texttt{t = a - b}.
|
||||
|
||||
Another instruction that is used is \texttt{testX src2, src1} (X again a size postfix), and acts like computing \texttt{a \& b} and where \texttt{ZF} is set if \texttt{a \& b == 0}
|
||||
and \texttt{SF} is set if \texttt{a \& b < 0}.
|
||||
|
||||
\content{Zeroing register} We can use a move instruction, but that is less efficient than using \texttt{xorl reg, reg}, where \texttt{reg} is the 32-bit version of the reg we want to zero.
|
||||
|
||||
\content{Reading condition codes} To read condition codes, we can use the \texttt{setC} instructions, where the \texttt{C} is to be substituted by an element of table \ref{tab:condition-codes}
|
||||
33
semester3/spca/parts/00_asm/03_operations/03_jumping.tex
Normal file
33
semester3/spca/parts/00_asm/03_operations/03_jumping.tex
Normal file
@@ -0,0 +1,33 @@
|
||||
\subsubsection{Jumping}
|
||||
To jump, use \texttt{jmp <label>} (unconditional jump) or the \texttt{jC} instructions, with \texttt{C} from table \ref{tab:condition-codes}
|
||||
|
||||
\begin{table}[h!]
|
||||
\begin{tables}{lll}{\texttt{setX} & Condition & Description}
|
||||
\texttt{e} & \verb|ZF| & Equal / Zero \\
|
||||
\texttt{ne} & \verb+~ZF+ & Not Equal / Not Zero \\
|
||||
\texttt{s} & \verb|SF| & Negative \\
|
||||
\texttt{ns} & \verb+~SF+ & Nonnegative \\
|
||||
\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) \\
|
||||
\texttt{a} & \verb+~CF&~ZF+ & Above (unsigned) \\
|
||||
\texttt{b} & \verb|CF| & Below (unsigned) \\
|
||||
\end{tables}
|
||||
\caption{Condition code postfixes for jump and set instructions}
|
||||
\label{tab:condition-codes}
|
||||
\end{table}
|
||||
|
||||
\content{Conditional Moves}
|
||||
|
||||
Similar to \texttt{jC}, the same postfixes can be applied to \texttt{cmovC}, for example:
|
||||
|
||||
\begin{minted}{gas}
|
||||
cmpl %eax, %edx
|
||||
cmovle %edx, %eax
|
||||
\end{minted}
|
||||
|
||||
Will move \verb|%edx| into \verb|%eax|, only if \verb|%edx| is less or equal (\verb|le|) \verb|%eax|.
|
||||
|
||||
This can be used to, for example, compile ternary expressions from \verb|C| to Assembly.
|
||||
However, this requires evaluating both possible expressions, which may lead to a (significant) performance overhead.
|
||||
@@ -35,5 +35,5 @@ The same function, using a \verb|while| loop instead may lead to this:
|
||||
Sparse switch statements are compiled as decision trees, whereas large switch statements may become \textit{jump tables}.
|
||||
|
||||
These jump tables are usually stored in the \texttt{.rodata} section with 8-byte alignment. The jump uses offsets:
|
||||
\mint{asm}|jmp *.LABEL(, %rsi, 8)|
|
||||
\mint{gas}|jmp *.LABEL(, %rsi, 8)|
|
||||
and we jump to the effective address of \texttt{.LABEL + rsi * 8}
|
||||
|
||||
@@ -4,7 +4,7 @@ In the below two, we can do this with $x = 1, 2, 4, 8$, each corresponding to a
|
||||
|
||||
\bi{Stack push} \texttt{pushX src}: Fetch operand at \texttt{src}, decrement \texttt{\%rsp} by $x$, then writes the operand at address of \texttt{\%rsp}
|
||||
|
||||
\bi{Stack pop} \texttt{popX dest}: Does the opposite, reads operand at \texttt{\%rsp}, increments it by $x$, then writes the operand into \texttt{dest}
|
||||
\bi{Stack pop} \texttt{popX dest}: Fetch operand at address of \texttt{\%rsp}, increment \texttt{\%rsp} by $x$, then writes the operand into \texttt{dest}
|
||||
|
||||
\content{Procedure call / return} Use \texttt{call LABEL}. This pushes return label to the stack and jumps to the LABEL.
|
||||
After this instruction, we also may use the \texttt{pushX} instruction to store further registers.
|
||||
@@ -49,4 +49,4 @@ If we can do all accesses to the stack relative to the stack pointer, we do not
|
||||
update \texttt{\%rbp} and not even \texttt{\%rbx}, or we can use it for other purposes.
|
||||
|
||||
We can also allocate the entire stack frame immediately by incrementing the stack pointer to the final position and then store data relative to it.
|
||||
To deallocate a stack frame, simply increment the stack pointer
|
||||
To deallocate a stack frame, simply increment the stack pointer.
|
||||
|
||||
6
semester3/spca/parts/01_c/04_variadic.tex
Normal file
6
semester3/spca/parts/01_c/04_variadic.tex
Normal file
@@ -0,0 +1,6 @@
|
||||
\newpage
|
||||
\subsection{Variadic functions}
|
||||
|
||||
Variadic functions take a variable number of arguments and use the \texttt{...} syntax in \lC.
|
||||
A notable example of such a function is \texttt{printf}
|
||||
\inputcodewithfilename{c}{code-examples/00_c/03_others/}{00_variadic.c}
|
||||
Reference in New Issue
Block a user