Last updated at 4 March 2022 at 8:43pm
So, I’m learning assembly. There’s something I’ve been wondering for quite some time now. I think I’ve figured it out.
If I’m wrong, I’d appreciate it if you reach out, :)
We have a finite number of registers at our disposal when working with assembly code.
mov r0, #10
mov r1, #10
add r0, r0, r1
The example above that adds two numbers.
The example uses both registers r0
and r1
.
The question or thing that I’ve been struggling with is,
r0
and r1
registers,
what happens when we make a function call, and both functions use r0
and r1
?
To explain the issue better, consider the following code snippets
void bar()
{
int a = 10; // mov r0, #10
int b = 10; // mov r1, #10
int c = a + b; // add r0, r0, r1
...
}
void foo()
{
int a = 12; // mov r0, #12
int b = 14; // mov r1, #14
...
bar(); // branch bar
int c = a + b; // add r0, r0, r1
...
}
r0
and r1
are being used by both, bar()
and foo()
.
But something is missing, when bar()
returns, that would mean the values of a
and b
would not be 12
and 14
as foo()
expects
since the values were tampered with by bar()
This is where the stack comes to the rescue. One of the uses of the stack is to save the values of the registers and restore them later.
So before using a register in bar()
we would need to push its value to the stack,
then once everything in bar()
is executed before returning, restore its value by popping the stack and set the registers to the appropriate values.
Here is what that looks like
.foo:
mov r0, #12
mov r1, #14
branch bar
; Continue execution
add r0, r0, r1
.bar:
; Push r0 and r1 to the stack
push r0
push r1
mov r0, #10
mov r1, #10
add r0, r0, r1
; Pop stack and set r0 and r1 values
pop r1, stack
pop r0, stack
; Return
ret .foo
Parts to pay attention to, since bar
will use r0
and r1
we push their values to the stack.
.bar:
push r0
push r1
...
And once we are done, just before returning, we pop the stack and set the values to the register. Also note the order of popping, the stack is LIFO(last in first out).
.bar:
...
pop r1
pop r0
; Return
ret .foo
pop
,branch
andpush
in this case are made up, but there should be similar/appropriate instructions to handle that.
Here is another question, that I’ve still not figured out.
Answer is here