mm2426
mm2426

Reputation: 33

Using Stack for variable allocation mips

I am trying to convert c functions into mips assembly code as a practice. I was trying to allocate the space on stack for local variables & function arguments. But I get alignment errors at run time. I know that the memory should be aligned with appropriate data structure (i.e. if we want to store a word to memory, the word address should be a multiple of 4 is my understanding and similar for half words). My problem is I am unable to figure it out how to handle this issue during a run time growing stack?

my c code is

int main(void){
int i, j;
i = 0;
j = 300;
foo(1, i, j);
return 0;
}
int foo(char a, int b, int c){
int x, y, z;
x = a+b;
y = c-a;
z = x+y;
return z;
}

My assembly code is

    .text
init:   li $sp, 0x1002FFFF  #initialize sp here
main:   
    addi $sp, $sp, -4   #allocate two 16 bit ints on stack (i,j local vars)
    sh $zero, 1($sp)    #i = 0 (i is always sp + 1)
    li $t0, 300     #move 300 to reg to init j (j is always sp + 3)
    sh $t0, 3($sp)      #j = 300 

    li $a0, 1       #load agruments of func foo in the arg regs
    lh $a1, 1($sp)      #load value of i
    lh $a2, 3($sp)      #load value of j
    jal foo         #call function
    move $a0, $v0       #move return value in a0 for disp
    li $v0, 1
    syscall
exit:
    li $v0, 10
    syscall

foo:    #There are alignment errors in ths code 
    #storing the values of args & local var is done in this code
    #this is of no use in this currently but will help 
    #in case if recurssion or other function calls are done in this fn
    addi $sp, $sp, -15  #15B allocated on stack for (RA + ARG + Local Vars
    sw $ra, ($sp)       #store return address starting from addr sp to sp+3 4B
    sb $a0, 4($sp)      #store 1st arg (char a) 
    sh $a1, 5($sp)      #store 2nd arg (int b)
    sh $a2, 7($sp)      #store 3rd arg (int c)
    add $t0, $a0, $a1   #Write function body starts (value of x computed)
    sh $t0, 9($sp)      #store value of x
    sub $t1, $a2, $a0   #calc Y = c - a
    sh $t1, 11($sp)     #store value of Y
    add $t0, $t0, $t1   #Calc Z = X + Y
    sh $t0, 13($sp)     #store value of Z
    move $v0, $t0       #store return value in v0 (Z val)
    lw $ra, ($sp)       #pop return address from the stack 
    addi $sp, $sp, 15   #Deallocate args from the stack
    jr $ra          #jump to return address

Upvotes: 1

Views: 1477

Answers (1)

markgz
markgz

Reputation: 6266

Take a look at the MIPS calling convention here. In particular, functions with four or fewer arguments pass the arguments in registers $a0,...,$a3. The stack pointer must always be four byte aligned, even when saving a value smaller than four bytes.

Upvotes: 1

Related Questions