From 9da3a2c0d39549b3ab5566c9bbdd52256f2ca377 Mon Sep 17 00:00:00 2001 From: Janis Hutz Date: Mon, 12 Jan 2026 12:02:53 +0100 Subject: [PATCH] [SPCA] Finish stack, data type compilation details --- .../00_c/03_others/00_variadic.c | 10 +++ semester3/spca/parts/00_asm/01_syntax.tex | 61 ------------- .../spca/parts/00_asm/01_syntax/00_intro.tex | 12 +++ .../parts/00_asm/01_syntax/01_registers.tex | 25 ++++++ .../00_asm/01_syntax/02_instructions.tex | 22 +++++ semester3/spca/parts/00_asm/02_data-types.tex | 6 -- .../00_asm/02_dtype-dstruct/00_data-types.tex | 19 ++++ .../00_asm/02_dtype-dstruct/01_arrays.tex | 7 ++ .../00_asm/02_dtype-dstruct/02_structs.tex | 24 +++++ .../02_dtype-dstruct/03_nested-arrays.tex | 14 +++ .../04_multi-level-arrays.tex | 8 ++ .../00_asm/02_dtype-dstruct/05_unions.tex | 2 + semester3/spca/parts/00_asm/03_operations.tex | 83 ------------------ .../parts/00_asm/03_operations/00_intro.tex | 9 ++ .../00_asm/03_operations/01_arithmetic.tex | 17 ++++ .../03_operations/02_condition-codes.tex | 24 +++++ .../parts/00_asm/03_operations/03_jumping.tex | 33 +++++++ .../spca/parts/00_asm/04_control-flow.tex | 2 +- semester3/spca/parts/00_asm/05_stack.tex | 4 +- semester3/spca/parts/01_c/04_variadic.tex | 6 ++ .../00_intro.tex | 0 semester3/spca/spca-summary.pdf | Bin 530278 -> 540978 bytes semester3/spca/spca-summary.tex | 23 ++++- 23 files changed, 255 insertions(+), 156 deletions(-) create mode 100644 semester3/spca/code-examples/00_c/03_others/00_variadic.c delete mode 100644 semester3/spca/parts/00_asm/01_syntax.tex create mode 100644 semester3/spca/parts/00_asm/01_syntax/00_intro.tex create mode 100644 semester3/spca/parts/00_asm/01_syntax/01_registers.tex create mode 100644 semester3/spca/parts/00_asm/01_syntax/02_instructions.tex delete mode 100644 semester3/spca/parts/00_asm/02_data-types.tex create mode 100644 semester3/spca/parts/00_asm/02_dtype-dstruct/00_data-types.tex create mode 100644 semester3/spca/parts/00_asm/02_dtype-dstruct/01_arrays.tex create mode 100644 semester3/spca/parts/00_asm/02_dtype-dstruct/02_structs.tex create mode 100644 semester3/spca/parts/00_asm/02_dtype-dstruct/03_nested-arrays.tex create mode 100644 semester3/spca/parts/00_asm/02_dtype-dstruct/04_multi-level-arrays.tex create mode 100644 semester3/spca/parts/00_asm/02_dtype-dstruct/05_unions.tex delete mode 100644 semester3/spca/parts/00_asm/03_operations.tex create mode 100644 semester3/spca/parts/00_asm/03_operations/00_intro.tex create mode 100644 semester3/spca/parts/00_asm/03_operations/01_arithmetic.tex create mode 100644 semester3/spca/parts/00_asm/03_operations/02_condition-codes.tex create mode 100644 semester3/spca/parts/00_asm/03_operations/03_jumping.tex create mode 100644 semester3/spca/parts/01_c/04_variadic.tex rename semester3/spca/parts/01_c/{04_floating-point => 05_floating-point}/00_intro.tex (100%) diff --git a/semester3/spca/code-examples/00_c/03_others/00_variadic.c b/semester3/spca/code-examples/00_c/03_others/00_variadic.c new file mode 100644 index 0000000..c344e02 --- /dev/null +++ b/semester3/spca/code-examples/00_c/03_others/00_variadic.c @@ -0,0 +1,10 @@ +#include // Variadic function utilities +#include + +void print_int( unsigned int num_ints, char *msg, ... ) { + va_list ap; // keeps track of current argument, similar (in concept) to iterator + va_start( ap, msg ); // Initialize the iterator based on last fixed arg + for ( int i = 0; i < num_ints; i++ ) + printf( "int %d = %d\n", i, va_arg( ap, int ) ); // Returns next arg cast to int + va_end( ap ); // Free up iterator +} diff --git a/semester3/spca/parts/00_asm/01_syntax.tex b/semester3/spca/parts/00_asm/01_syntax.tex deleted file mode 100644 index ff31e63..0000000 --- a/semester3/spca/parts/00_asm/01_syntax.tex +++ /dev/null @@ -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. diff --git a/semester3/spca/parts/00_asm/01_syntax/00_intro.tex b/semester3/spca/parts/00_asm/01_syntax/00_intro.tex new file mode 100644 index 0000000..5ff91c2 --- /dev/null +++ b/semester3/spca/parts/00_asm/01_syntax/00_intro.tex @@ -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. diff --git a/semester3/spca/parts/00_asm/01_syntax/01_registers.tex b/semester3/spca/parts/00_asm/01_syntax/01_registers.tex new file mode 100644 index 0000000..8973d54 --- /dev/null +++ b/semester3/spca/parts/00_asm/01_syntax/01_registers.tex @@ -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} diff --git a/semester3/spca/parts/00_asm/01_syntax/02_instructions.tex b/semester3/spca/parts/00_asm/01_syntax/02_instructions.tex new file mode 100644 index 0000000..eeffa01 --- /dev/null +++ b/semester3/spca/parts/00_asm/01_syntax/02_instructions.tex @@ -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. diff --git a/semester3/spca/parts/00_asm/02_data-types.tex b/semester3/spca/parts/00_asm/02_data-types.tex deleted file mode 100644 index af3d783..0000000 --- a/semester3/spca/parts/00_asm/02_data-types.tex +++ /dev/null @@ -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} diff --git a/semester3/spca/parts/00_asm/02_dtype-dstruct/00_data-types.tex b/semester3/spca/parts/00_asm/02_dtype-dstruct/00_data-types.tex new file mode 100644 index 0000000..182c4f5 --- /dev/null +++ b/semester3/spca/parts/00_asm/02_dtype-dstruct/00_data-types.tex @@ -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. diff --git a/semester3/spca/parts/00_asm/02_dtype-dstruct/01_arrays.tex b/semester3/spca/parts/00_asm/02_dtype-dstruct/01_arrays.tex new file mode 100644 index 0000000..1e0d14e --- /dev/null +++ b/semester3/spca/parts/00_asm/02_dtype-dstruct/01_arrays.tex @@ -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. diff --git a/semester3/spca/parts/00_asm/02_dtype-dstruct/02_structs.tex b/semester3/spca/parts/00_asm/02_dtype-dstruct/02_structs.tex new file mode 100644 index 0000000..801f3b7 --- /dev/null +++ b/semester3/spca/parts/00_asm/02_dtype-dstruct/02_structs.tex @@ -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. diff --git a/semester3/spca/parts/00_asm/02_dtype-dstruct/03_nested-arrays.tex b/semester3/spca/parts/00_asm/02_dtype-dstruct/03_nested-arrays.tex new file mode 100644 index 0000000..b8c8a09 --- /dev/null +++ b/semester3/spca/parts/00_asm/02_dtype-dstruct/03_nested-arrays.tex @@ -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. + diff --git a/semester3/spca/parts/00_asm/02_dtype-dstruct/04_multi-level-arrays.tex b/semester3/spca/parts/00_asm/02_dtype-dstruct/04_multi-level-arrays.tex new file mode 100644 index 0000000..9b201c7 --- /dev/null +++ b/semester3/spca/parts/00_asm/02_dtype-dstruct/04_multi-level-arrays.tex @@ -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. diff --git a/semester3/spca/parts/00_asm/02_dtype-dstruct/05_unions.tex b/semester3/spca/parts/00_asm/02_dtype-dstruct/05_unions.tex new file mode 100644 index 0000000..add0b6c --- /dev/null +++ b/semester3/spca/parts/00_asm/02_dtype-dstruct/05_unions.tex @@ -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. diff --git a/semester3/spca/parts/00_asm/03_operations.tex b/semester3/spca/parts/00_asm/03_operations.tex deleted file mode 100644 index d70e503..0000000 --- a/semester3/spca/parts/00_asm/03_operations.tex +++ /dev/null @@ -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