在这里感觉有点傻,试图弄清楚这条线在做什么:
addiu sp,sp,-24
我知道它正在设置堆栈指针,我的困惑是addiu
部分。它将UNSIGNED -24
添加到堆栈指针,并将其存储回堆栈指针。
sp
取16位-24(FFE8
)的值(addiu
操作的“立即”值是16位宽)还是扩展了符号到完整的32位?
另外,在此指令之前是sp=0
吗?它是一段琐碎的c代码中的第一条指令。
我正在将MIPS核心作为个人项目实施,这让我有点难过。
答案 0 :(得分:2)
addiu指令包括一个16位立即数操作数。当ALU执行指令时,立即操作数被符号扩展为32位。如果在加法期间发生二次补码溢出,则忽略它。
<a href=....
答案 1 :(得分:1)
MIPS支持四种基本算术运算:加法,减法,乘法和 分裂。
添加说明:基本添加说明
add Rdest,Rsrc1,Rsrc2
添加Rsrc1
和Rsrc2
的内容,并将结果存储在Rdest
中。这些数字被视为有符号整数。如果发生溢出,则会生成溢出异常。如果不需要溢出异常,则可以使用addu
。
第二个操作数可以指定为immediate 16-bit number
。格式为:
addi Rdest,Rsrc1,imm
16-bit
值为sign-extended to 32 bits
,并添加到Rsrc1
的内容中。与add指令一样,会生成溢出异常。另外,如果不需要溢出异常,我们可以使用addiu
。
MIPS没有明确支持堆栈操作。相比之下,它
提供诸如push和pop之类的指令以便于堆栈操作。此外,还有一个特殊的堆栈指针寄存器sp
,用于保存堆栈顶部信息。在MIPS中,寄存器扮演堆栈指针的角色。我们必须操纵这个寄存器来实现堆栈。
例如,堆栈向下增长(即,当我们将项目推入堆栈时,地址会减少)。因此,当在堆栈上保留空间以推送值时,我们必须减少sp
值。因此,执行开始时堆栈指针的相对值可以取为零。
例如,要推送寄存器a0
和ra
,我们必须保留8个字节的堆栈空间,并使用sw
来推送值,如下所示:
sub $sp,$sp,8 # reserve 8 bytes of stack
sw $a0,0($sp) # save registers
sw $ra,4($sp)
此序列通常在过程开始时用于保存寄存器。要在从过程返回之前恢复这些寄存器,我们可以使用以下序列:
lw $a0,0($sp) # restore the two registers
lw $ra,4($sp)
addu $sp,$sp,8 # clear 8 bytes of stack
那么,你的第一个问题的答案是:
16-bit
值为sign-extended to 32 bits
,并添加到Rsrc1
的内容中。
和你的第二个问题:
因此,执行开始时堆栈指针的相对值可以取为零。