Assembly 通过帧指针mips访问分配内存时出现SEGFULT
我正在编写一个从c90到MIPS的简单编译器,我正处于代码生成阶段。我将此c代码作为输入:Assembly 通过帧指针mips访问分配内存时出现SEGFULT,assembly,segmentation-fault,stack,mips,mips32,Assembly,Segmentation Fault,Stack,Mips,Mips32,我正在编写一个从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 mem
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)
(在程序集底部附近)时,我遇到了SEGFULT。如果我尝试通过$sp
访问内存位置,它将正常工作。此外,如果我在函数开始时分配总内存(即,addiu$sp,$sp,-52,并且不执行第二次分配),它也能正常工作
我遗漏了什么?你为什么认为24($fp)
有意义?从堆栈中分配24个字节,然后将$fp
16个字节指向堆栈(与您的注释相反,它不是底部)。因此,$fp
的有效偏移量在[-16,+8)
的范围内。但我只在分配了另外28个字节后访问24($fp)…我同意您的所有其他参数。但是分配的内容将位于$fp
的更多负地址。在分配这些地址后(保持$fp
不变),有效范围当然是[-44,+8)
…它不是向上增长的,而是减去的(因为堆栈向下增长,所以你应该减去)。天哪,非常感谢,这很明显…这就是人们不应该这样做的原因