I'm writing a tinyc Compiler which translates into MIPS assembly. I'm stuck with the question how to implement the local variable handling. The following example makes it hard to think of a proper solution:
int* funcA() {
int a = 3;
return &a;
}
int main() {
return *(funcA());
}
Normally you would create the local variable on the stack. So in this case 'int a' would be created on the stack. The problem is that in the end we want to return the address of 'a' and not the value with &a. But in the moment we leave 'funcA()' we reset the stack to the old state and the pointer we return in the end is not valid anymore and could show later into nirvana.
My first attempt was to handle everything with registers, but with the &-Operator we translate it to something like this:
.globl funcA
funcA:
addiu $sp, $sp, -4 # save return address
sw $ra, ($sp)
addiu $sp, $sp, -4 # save the reg we will use for further processing
sw $s0, ($sp)
addiu $t0, $zero, 3 # $t0 = a and add 3
la $s0, ($t0)
la $t0, ($s0)
sw $t1, ($t0) # crashes here
la $v0, ($t1) # put the result in $v0
lw $s0, ($sp)
addiu $sp, $sp, 4 # restore the stack
lw $ra, ($sp)
addiu $sp, $sp, 4
jr $ra # jump back
It would crash in the marked line because the destination register doesn't have an address to store something. One idea is to to create a datasegment for every local variable, but that would be a overhead and it wouldn't work with recursive functions.
Does anyone have a proper solution how to handle local variables especially if you return an address from a local variable and not a value?
Any help is appreciated!
int aon the stack and returning a pointer to it. For example, the mingw32-gcc compiler will warn you about yourint* funcA()- warning: function returns address of local variable. - embedded_guy