[SPCA] ASM ops, basic syntax

This commit is contained in:
2026-01-10 08:36:28 +01:00
parent 02f6df0138
commit 722759c1e8
6 changed files with 70 additions and 5 deletions

Binary file not shown.

View File

@@ -0,0 +1,2 @@
main:
addl 8(%rbp), %eax # Add long

View File

@@ -1,2 +0,0 @@
main:
addl 8(%rbp), %eax // Add long

View File

@@ -38,7 +38,7 @@ 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} 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} \subsubsection{Instructions}
Instructions usually have a 3 letter prefix with a one letter postfix, where the postfix indicates the number of bytes. 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 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, The following options can be passed for source and destination: Registers,
@@ -51,9 +51,11 @@ The instruction will then read the number of bytes, as specified by the postfix
The full syntax for memory address modes is \texttt{D(Rb, Ri, S)}, where The full syntax for memory address modes is \texttt{D(Rb, Ri, S)}, where
\begin{itemize}[noitemsep] \begin{itemize}[noitemsep]
\item \texttt{D}: Displacement (constant offset), should be 0, 1, 2 or 4 bytes % TODO: This seems to conflict with examples \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{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{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) \item \texttt{S}: Scale factor (1, 2, 4 or 8, to correct offsets)
\end{itemize} \end{itemize}
The computation that then happens is the following: \texttt{Mem[ Reg[Rb] + S * Reg[Ri] + D ]} 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.

View File

@@ -1,3 +1,66 @@
\subsection{Operations} \subsection{Operations}
Assembly operations include performing arithmetic or logic functions on registers or memory data, 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) transferring data between memory and registers and transferring control (conditional or unconditional jumps)
Most of the memory-related instructions in \texttt{x86} assembly have the format
\mint{asm}|movq dest, src|
whereas arithmetic / logic operations have the format inversed (below \texttt{X} is to be replced with size postfix).
\begin{tables}{lll}{Mnemonic & Format & Computation}
\texttt{addl} & \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 and jumping}
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, 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}, 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{setX} instructions, where the \texttt{X} 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{jX} instructions, with \texttt{X} 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}

Binary file not shown.