Yes.
Programming languages have global variables. Also, an inner program block can use variables that are not its local variables which are defined in a containing block. Let us skip these messy details and implement local variables, only. The details may be convered in a course on compilers or in a course on programming languages.
The picture shows what a stack frame (in our simplified format) looks like when a subroutine is active . As always (for us), each item on the stack is four bytes long.
As previously, the caller saves the "T" registers
that contain values it needs, and
the callee (the subroutine) saves the "S" registers
it might change.
But now room is pushed onto the stack for (in the example)
four local variables a, b, i
and j
.
While the subroutine is active, the frame pointer, register $30, points to the top of the stack. (Remember, our stacks grow downward, so in the picture $fp is correctly pointing at the last word that was pushed onto the stack, the "top" of the stack.)