简体   繁体   English

MIPS堆栈指针

[英]MIPS stack pointer

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. 我了解它正在设置堆栈指针,我的困惑是addiu部分。 It's adding the UNSIGNED -24 to the stack pointer, and storing it back in the stack pointer. 它将UNSIGNED -24添加到堆栈指针,并将其存储回堆栈指针。

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? sp是采用16位-24( FFE8 )的值( addiu操作的“立即”值是16位宽)还是将符号扩展到完整的32位?

Also, is sp=0 prior to this instruction? 另外,在此指令之前sp=0吗? It is the first instruction in a trivial piece of c code. 这是一段琐碎的C代码中的第一条指令。

I'm implementing a MIPS core as a personal project, and this has me a little stumped. 我正在将MIPS核心作为个人项目实施,这让我有些困惑。

The addiu instruction includes a 16-bit immediate operand. addiu指令包含一个16位立即数。 When the ALU executes the instruction, the immediate operand is sign-extended to 32 bits. 当ALU执行指令时,立即数被符号扩展为32位。 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.

Arithmetic Instructions 算术指令

MIPS supports the four basic arithmetic operations: addition, subtraction, multiplication, and division. MIPS支持四种基本的算术运算:加法,减法,乘法和除法。

Addition Instructions : The basic addition instruction 添加说明 :基本添加说明

 add Rdest,Rsrc1,Rsrc2

adds contents of Rsrc1 and Rsrc2 and stores the result in Rdest . 添加Rsrc1Rsrc2内容, Rsrc1结果存储在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. 如果不需要溢出异常,则可以使用addu

The second operand can be specified as an immediate 16-bit number . 可以将第二个操作数指定为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 . 16-bit值将sign-extended to 32 bits并添加到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. 与添加一样,如果不需要溢出异常,我们可以使用addiu

Stack Implementation 堆栈实施

The MIPS does not explicitly support stack operations. MIPS不明确支持堆栈操作。 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. 此外,还有一个特殊的堆栈指针寄存器sp ,用于保存堆栈顶部信息。 In the MIPS, a register plays the role of the stack pointer. 在MIPS中,寄存器充当堆栈指针的角色。 We have to manipulate this register to implement the stack. 我们必须操纵该寄存器来实现堆栈。

For example, the stack grows downward (ie, 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. 因此,当在堆栈上保留用于推入值的空间时,我们必须减小sp值。 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: 例如,要推送寄存器a0ra ,我们必须保留八个字节的堆栈空间,并使用sw推送值,如下所示:

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 is sign-extended to 32 bits and added to the contents of Rsrc1 . 16-bit值将sign-extended to 32 bits并添加到Rsrc1的内容中。

and to your second question: 和第二个问题:

Thus, the relative value of the stack pointer at the beginning of execution could be taken as zero. 因此,在执行开始时堆栈指针的相对值可以视为零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM