含数组的C语言循环转MIPS汇编(栈实现)的疑问咨询
关于C转MIPS汇编的疑问解析
先把原C代码贴出来方便对照:
void subr1(char *a, int v[]) { int i; char c[12]; for (i=11; i >= 0; i--) { v[i] = subr2(c[i], *a); } }
再看看教授给出的带你的疑惑标注的汇编代码:
addiu $sp,$sp,-28 # Activation block(疑惑:为什么是-28?栈帧大小怎么算的?) sw $ra, 24($sp) # Space for $ra (4 bytes) sw $s0, 20($sp) # Space for *a(疑惑:$s0用来保存*a?为什么不用临时寄存器?) sw $s1, 16($sp) # Space for v[](疑惑:同理,$s1存v的地址?) sw $s2, 12($sp) # Space for i(疑惑:循环变量i存在$s2?) # 这里是不是还有c[12]的空间?12字节的char数组,那栈帧里的分配怎么对应? move $s0, $a0 # 把参数a($a0)存入$s0 move $s1, $a1 # 把参数v($a1)存入$s1 li $s2, 11 # i = 11,初始化循环变量 loop: sll $t0, $s2, 2 # t0 = i * 4(因为v是int数组,每个元素4字节) add $t1, $s1, $t0 # t1 = v + i*4,即&v[i] sll $t0, $s2, 0 # t0 = i(因为c是char数组,每个元素1字节,左移0位就是i本身) add $t2, $sp, $t0 # t2 = sp + i?不对啊,c[12]是在栈里的,那c的起始地址是哪里? lb $a0, 0($t2) # a0 = c[i](疑惑:这里的地址计算是不是有问题?) lb $a1, 0($s0) # a1 = *a,取a指向的char值 jal subr2 # 调用subr2,返回值在$v0 sw $v0, 0($t1) # v[i] = 返回值 addi $s2, $s2, -1 # i-- bge $s2, $zero, loop # i >=0 继续循环 lw $s2, 12($sp) # 恢复$s2 lw $s1, 16($sp) # 恢复$s1 lw $s0, 20($sp) # 恢复$s0 lw $ra, 24($sp) # 恢复$ra addiu $sp,$sp,28 # 释放栈帧 jr $ra # 返回
接下来逐个解答你的疑惑:
栈帧大小为什么是28字节?
咱们掰着手指头算:MIPS栈是向下增长的,这个函数的栈帧需要容纳这些内容:- 4个需要保存的寄存器:$ra(4字节)、$s0(4字节)、$s1(4字节)、$s2(4字节)→ 加起来16字节
- 局部char数组
c[12]→ 12字节
16+12=28,刚好对应addiu $sp,$sp,-28。另外MIPS通常要求栈对齐到8字节,28是4的倍数,但这里刚好凑齐,完全符合要求。
为什么用$s系列寄存器保存参数和循环变量?
MIPS的调用约定里,$s0-$s7是保存寄存器(saved registers)——意思是如果当前函数要使用这些寄存器,必须先把它们原来的值存到栈里,函数返回前再恢复。而$t0-$t9是临时寄存器,不需要保存,调用其他函数时很可能被修改。
这里循环变量i在整个循环过程中要持续使用,而且调用subr2的时候临时寄存器可能会被覆盖,所以用$s2保存i更稳妥;同理,*a和v[]是函数的输入参数,整个函数执行过程中都要访问,存在$s0、$s1里既不用每次重新从参数寄存器取,也能避免被临时寄存器的操作冲掉。c[i]的地址计算是不是正确?
完全没问题!你看,add $t2, $sp, $t0里的$t0就是i(sll $t0, $s2, 0就是把i的值直接赋给t0,左移0位等于没操作)。而c[12]的起始地址就是当前的$sp——因为我们刚把栈指针减了28,栈帧最底部($sp指向的位置)就是c[0],$sp+11就是c[11],所以当i=11时,$sp+11正好对应c[11],完美匹配循环的起始值。而且char是1字节,所以直接用i作为偏移量就行,不用像int数组那样乘4。关于栈帧里的空间分配对应关系
给你理一下栈帧的布局(从高地址到低地址,因为栈向下增长):- 24($sp):保存的$ra(4字节)
- 20($sp):保存的$s0(4字节)
- 16($sp):保存的$s1(4字节)
- 12($sp):保存的$s2(4字节)
- 0($sp)到11($sp):char数组c[12](12字节)
这样整个栈帧从$sp到$sp+27,总共28字节,完全对应上。
内容的提问来源于stack exchange,提问作者Arnau
相关产品推荐
相关产品推荐

