diff options
Diffstat (limited to 'thesis/fix-storing-pc.tex')
-rw-r--r-- | thesis/fix-storing-pc.tex | 87 |
1 files changed, 0 insertions, 87 deletions
diff --git a/thesis/fix-storing-pc.tex b/thesis/fix-storing-pc.tex deleted file mode 100644 index 31381f0..0000000 --- a/thesis/fix-storing-pc.tex +++ /dev/null @@ -1,87 +0,0 @@ -\section{Storing the program counter} -\label{sec:fix-storing-pc} - -\begin{multicols}{2} - -The first issue I ran into is that of storing the program counter. -Storing the program counter on the stack is something done commonly in many languages during a function call. - -\subsection{ARM code example} -Usually, an offset to the actual program counter at the moment of the store instruction is stored, -to allow for a branch after that instruction, and have the callee return to the address after that branch. -The ARM architecture accommodates for this: an instruction that reads the program counter, actually reads - \enquote{the address of the current instruction plus 8}~\cite[A2.3]{armv7ar}. -The following ARM assembly example illustrates this (\texttt{armstartup.s:540-2},~\cite{armrts}): - -\begin{minted}{ual} - str pc,[sp,#-4]! - bl init_clean - tst r4,r4 -\end{minted} - -\begin{lrbox}{\ualbox} - \ual{[sp,#-4]!} -\end{lrbox} - -Dummy addresses have been indicated in comments. -When execution arrives at \ual{0x20}, the program counter is set to \ual{0x20}. -Per the above documentation, \ual{str} stores \ual{0x20+8} on the stack% - \footnote{\usebox{\ualbox} - indicates that the stack pointer should be decreased by four before storing the program counter on the stack. - It has nothing to do with the 8 offset that is added to the program counter itself.}. -The processor branches to \ual{init_clean}, - which loads the value from the stack back into the program counter to return to the caller. -The program counter is then \ual{0x28}. -For the next instruction cycle, the \ual{tst} command is executed. - -\subsection{Adapting for Thumb-2} -There are two reasons why the above cannot be used in Thumb-2 code. - -First, \ual{pc} is not allowed as the first operand to a \ual{str} instruction. -Hence, we need to first move \ual{pc} to an auxiliary register, and then push that on the stack. -We then get: - -\begin{minted}{ual} - add lr,pc,#9 - str lr,[sp,#-4]! - bl init_clean - tst r4,r4 -\end{minted} - -We store the value \ual{0x2d}. -This address points to the \ual{tst} instruction as before, with the LSB set to 1 to indicate Thumb mode. - -The second problem we meet is that the instruction to store the program counter may be halfword-aligned rather than word-aligned. -We saw above that a read of the program counter in ARM mode reads as PC+8. -In Thumb mode this is more complicated. -In this case, we - \enquote{[r]ead the word-aligned PC value, that is, - the address of the current instruction + 4, - with bits [1:0] forced to zero}~\cite[A5.1.2]{armv7m}. -This means that when the \ual{add} instruction above is at \ual{0x22}, - we will still store \ual{0x2d} on the stack, - since the word-aligned program counter is \ual{0x20} as before. -However, in this case \ual{bl} is located at \ual{0x2a}, and since this is a 32 bits instruction we point to the middle of that instruction. - -In hand-written code, we can solve this by adding labels for the addresses we want to store on the stack. -In generated code, we need to keep track of the current alignment and add either 9 or 11 to the read program counter. - -\subsection{Other solutions} -Another solution than the one we present here is the use of the link register. -Branch instructions as \ual{bl} store the address of the next instruction in the link register. -We could therefore imagine a setup where the callee gets the return address from that register rather than from the stack. -This is the approach taken by GCC. -The code of a typical C subroutine starts with \ual{push {r7,lr}} and ends with \ual{pop {r7,pc}}. - -When generating code for a functional language, this is not easily done due to tail recursion. -It is an easier solution to have the caller responsible for storing the return address, - which is why this approach is taken in Clean's ARM code generator\cite{armcg} - and why I continue along those lines. - -\subsection{Complexity analysis} -To be done. %TODO - -For every occurrence: +1 word code size; -for every function call: +1 instruction. - -\end{multicols} |