我正在编写一个从c90到MIPS的简单编译器,我正处于代码生成阶段。我有这个c代码作为输入:
int main(){
int a=50, b=10, c=a+b;
return c;
}
我的编译器生成的代码是:
.text
.align 2
.globl main
.ent main
.type main, @function
main:
addiu $sp, $sp, -24 # Allocate memory on the stack
sw $fp, 20($sp) # Store value of fp on the bottom of the stack
addiu $fp, $sp, 16 # Modify fp to point to the the bottom of the available stack memory
sw $ra, 0($fp) # Store the return address for the subroutine
li $t0, 50
sw $t0, 4($fp)
li $t0, 10
sw $t0, 8($fp)
addiu $sp, $sp, -28 # Allocate more memory
lw $t0, 4($fp)
sw $t0, 16($fp)
lw $t0, 8($fp)
sw $t0, 20($fp)
lw $t0, 16($fp)
lw $t1, 20($fp)
addu $t2, $t0, $t1
sw $t2, 12($fp)
lw $t0, 12($fp)
sw $t0, 24($fp)
lw $v0, 24($fp)
lw $ra, 0($fp) # Load return address in register 31
lw $fp, -4($fp) # Restore the value of the frame pointer
addiu $sp, $sp, 52 # Restore the value of the stack pointer
j $ra
nop
.end main
现在抛开代码效率不高的事实,我使用的帧指针与MIPS约定略有不同,我恢复了$sp
和$fp
的初始值,这是我的所有代码需要与其他功能一起运行。
问题是当我尝试访问内存地址24($fp)
(在程序集底部附近)时,我遇到了段错误。如果我尝试通过$sp
访问内存位置,则一切正常。此外,如果我在函数的开头分配总内存(即addiu $sp, $sp, -52
并且不执行第二次分配),它也可以正常工作。
我错过了什么?