Recall we had trouble performing the following computation:
result = square(3) + square(4); |
This code will not work all the time:
/* ------------------------------------------------- Call square(3) ------------------------------------------------- */ mov r0, #3 bl square mov r10, r0 // Save 3^2 in r10 *** FAIL !!! /* ------------------------------------------------- Call square(4) ------------------------------------------------- */ mov r0, #4 bl square <--- r10 overwritten by this call add r0, r0, r10 // FAIL to compute 32 + 42 |
DEMO: /home/cs255001/demo/asm/8-sub/reg-problem.s
|
In general: the stack right before and right fater a function call are equal in content
.... instr1 <------+ push parameters | The content of the bl f | runtime stack are pop parameters | equal at these instructions instr2 <------+ |
There is a very simple technique to perserve values in registers when you need to make a function call:
.... // How to perserve the value in register r0 // we need to make a function call push {r0} // Save r0 on stack <------+ push parameters | The content of the bl f | runtime stack are pop parameters | equal at these instructions <------+ push {r0} // Restore the old r0 value |
Example: result = square(3) + square(4);
mov r0, #3 bl square push {r0} // Save 32 in stack *** !!! mov r0, #4 bl square pop {r1} // Retrieve 32 from stack *** !!! add r0, r0, r1 // Computes 32+ 42 /* ------------------------------------------------- Store in result ------------------------------------------------- */ movw r1, #:lower16:result movt r1, #:upper16:result str r0, [r1] |
DEMO:
/home/cs255001/demo/asm/reg-problem.s
Note: this
technique will
also work when
parameters + local vars are
in the stack