diff options
author | Camil Staps | 2016-09-28 12:54:01 +0200 |
---|---|---|
committer | Camil Staps | 2016-09-28 12:54:01 +0200 |
commit | 8f07c77098c8624859660be7c65398870b921c20 (patch) | |
tree | 98ebd011e6ac502915ca24f3591b23079e95a2b5 /thesis/fix-storing-pc.tex | |
parent | Start thesis (diff) |
More on fixing the program counter
Diffstat (limited to 'thesis/fix-storing-pc.tex')
-rw-r--r-- | thesis/fix-storing-pc.tex | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/thesis/fix-storing-pc.tex b/thesis/fix-storing-pc.tex index 3b96314..4a203b3 100644 --- a/thesis/fix-storing-pc.tex +++ b/thesis/fix-storing-pc.tex @@ -8,7 +8,7 @@ Usually, an offset to the actual program counter at the moment of the store inst 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}): +The following ARM assembly example illustrates this (\texttt{armstartup.s:540-2},~\cite{armrts}): \begin{minted}{ual} str pc,[sp,#-4]! @ 0x20 Store PC on the stack @@ -16,10 +16,14 @@ The following ARM assembly example illustrates this (\texttt{armstartup.s:540-2} tst r4,r4 @ 0x28 \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{\ual{[sp,#-4]!} + \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}, @@ -27,7 +31,7 @@ The processor branches to \ual{init_clean}, The program counter is then \ual{0x28}. For the next instruction cycle, the \ual{tst} command is executed. -\subsubsection{Problems in Thumb-2} +\subsubsection{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. @@ -59,7 +63,20 @@ However, in this case \ual{bl} is located at \ual{0x2a}, and since this is a 32 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 \ual{9} or \ual{11} to the read program counter. +\subsubsection{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. + \subsubsection{Complexity analysis} -To be done. For every occurrence: +To be done. %TODO -Code size: +1 word; instructions: +1 +For every occurrence: +1 word code size; +for every function call: +1 instruction. |