I was under the impression that the frame pointer $fp is set to the first word of stack according to Computer Organization and Design MIPS 5th ed page 103.
int func(int g) {
int f = 9;
return g+f;
}
mips gcc 12.2.0 generated assembly code.
func:
addiu $sp,$sp,-24
sw $fp,20($sp)
move $fp,$sp
sw $4,24($fp)
li $2,9 # 0x9
sw $2,8($fp)
lw $3,24($fp)
lw $2,8($fp)
nop
addu $2,$3,$2
move $sp,$fp
lw $fp,20($sp)
addiu $sp,$sp,24
jr $31
nop
Is it valid that $fp (frame pointer) and $sp (stack pointer) contain the same address? I would have thought $fp would point to the first word on the stack i.e
func:
addiu $sp,$sp,-24
sw $fp,20($sp)
addiu $fp,$sp,20 #let $fp point to the first word on the stack
Are there any rules on which part of the stack $fp should point to or is it all dependent on the descretion of the software developer/compiler?

GCC seems to follow the ABI linked in this answer.
That ABI mandates:
So it's not possible to implement the frame pointer as depicted in the book, which would require a
move $fp, $spand then anaddiu $sp, $sp, XX.So the code generated by GCC (without optimizations) according to this ABI has an
fpbelow the frame.The ABI also mandates a homing/shadow area: even though the first four args are not passed on the stack, the caller must always reserve the corresponding space on the stack so that the callee can save the arg registers on that space.
You can see this behavior by looking at the instruction
sw $4,24($fp)and noting that$fp + 24 = original $sp = just above the allocated frame.This means that even non-leaf functions (functions that call other functions) will generally have
$sp=$fpbecause the compiler knows how much space it needs.But you can create cases where this is not true, for example by using the infamous
alloca:This code is compiled (without optimizations) to:
It may be worth drawing the state of the stack to better understand what's going on.
In general, the frame handling strategy used by the compilers will vary with time and you must take what's written in books with a grain of salt because nobody has the time or possibility to update and republish a book each time a new version of a compiler is released.
Just be sure to understand how the examples in the book work and you'll be able to adapt to new conventions pretty easily.