使用 Stack 进行变量分配 mip
Using Stack for variable allocation mips
我正在尝试将 c 函数转换为 mips 汇编代码作为练习。
我试图在堆栈上为局部变量和函数参数分配 space 。但是我在 运行 时出现对齐错误。我知道内存应该与适当的数据结构对齐(即,如果我们想将一个字存储到内存中,字地址应该是 4 的倍数是我的理解,半字类似)。
我的问题是我无法弄清楚如何在 运行 时间增长堆栈期间处理这个问题?
我的 C 代码是
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;
}
我的汇编代码是
.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
看看 MIPS 调用约定 here。
特别是,具有四个或更少参数的函数在寄存器 $a0,...,$a3
中传递参数。堆栈指针必须始终四字节对齐,即使保存的值小于四字节。
我正在尝试将 c 函数转换为 mips 汇编代码作为练习。 我试图在堆栈上为局部变量和函数参数分配 space 。但是我在 运行 时出现对齐错误。我知道内存应该与适当的数据结构对齐(即,如果我们想将一个字存储到内存中,字地址应该是 4 的倍数是我的理解,半字类似)。 我的问题是我无法弄清楚如何在 运行 时间增长堆栈期间处理这个问题?
我的 C 代码是
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;
}
我的汇编代码是
.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
看看 MIPS 调用约定 here。
特别是,具有四个或更少参数的函数在寄存器 $a0,...,$a3
中传递参数。堆栈指针必须始终四字节对齐,即使保存的值小于四字节。