Reputation: 2992
Feeling a little silly here, trying to work out what this line is doing:
addiu sp,sp,-24
I understand that it is setting the stack pointer, my confusion is the addiu
part. It's adding the UNSIGNED -24
to the stack pointer, and storing it back in the stack pointer.
Does sp
take the value of the 16 bit -24(FFE8
) (the "immediate" value of the addiu
operation is 16 bits wide) or does it extend the sign to the full 32 bits?
Also, is sp=0
prior to this instruction? It is the first instruction in a trivial piece of c code.
I'm implementing a MIPS core as a personal project, and this has me a little stumped.
Upvotes: 3
Views: 4027
Reputation: 6467
MIPS supports the four basic arithmetic operations: addition, subtraction, multiplication, and division.
Addition Instructions: The basic addition instruction
add Rdest,Rsrc1,Rsrc2
adds contents of Rsrc1
and Rsrc2
and stores the result in Rdest
. The numbers are treated as signed integers. In case of an overflow, an overflow exception is generated. addu
can be used if no overflow exception is needed.
The second operand can be specified as an immediate 16-bit number
. The format is:
addi Rdest,Rsrc1,imm
The 16-bit
value is sign-extended to 32 bits
and added to the contents of Rsrc1
. As in the add instruction, an overflow exception is generated. As in add, we can use addiu
if an overflow exception is not needed.
The MIPS does not explicitly support stack operations. In contrast, it
provides instructions such as push and pop to facilitate stack operations. In addition, there is a special stack pointer register sp
that keeps the top-of-stack information. In the MIPS, a register plays the role of the stack pointer. We have to manipulate this register to implement the stack.
For example, the stack grows downward (i.e., as we push items onto the stack, the address de- creases). Thus, when reserving space on the stack for pushing values, we have to decrease the sp
value. Thus, the relative value of the stack pointer at the beginning of execution could be taken as zero.
For example, to push registers a0
and ra
, we have to reserve eight bytes of stack space and use sw
to push the values as shown below:
sub $sp,$sp,8 # reserve 8 bytes of stack
sw $a0,0($sp) # save registers
sw $ra,4($sp)
This sequence is typically used at the beginning of a procedure to save registers. To restore these registers before returning from the procedure, we can use the following sequence:
lw $a0,0($sp) # restore the two registers
lw $ra,4($sp)
addu $sp,$sp,8 # clear 8 bytes of stack
So, the answer to your first question:
The
16-bit
value issign-extended to 32 bits
and added to the contents ofRsrc1
.
and to your second question:
Thus, the relative value of the stack pointer at the beginning of execution could be taken as zero.
Upvotes: 1
Reputation: 16223
The addiu instruction includes a 16-bit immediate operand. When the ALU executes the instruction, the immediate operand is sign-extended to 32 bits. If two's complement overflow occurs during the addition, it is ignored.
addiu d,s,const # $d <—— s + const.
# Const is 16-bit two's comp. sign-extended to 32 bits
# when the addition is done. No overflow trap.
Upvotes: 2