Assembly MIPS寄存器$v0/$a0

Assembly MIPS寄存器$v0/$a0,assembly,mips,Assembly,Mips,据我所知,$v0、

据我所知,
$v0、
是功能结果寄存器,
$v0
为32位,
$v1
为64位

我还知道,
$ao-$a3
是保存整数类型变量的函数参数寄存器


我知道这两种方法都不会在函数调用中保留,但我不知道MIPS中是否有文字用法?在什么情况下我们需要使用这些寄存器?

如果您计划调用其他使用MIPS ABI(应用程序二进制接口)的函数,则需要使用这些寄存器。这是一种让不同的代码模块就彼此接口的通用方式达成一致的方法。想象一下,如果每个程序员或编译器都选择自己的一组寄存器来传递参数和返回值,会有多糟

让我们看看C编译器为一小段代码生成了什么:

int multwoplusone(int arg)
{
    return arg*2 + 1;
}

int main()
{
    int i = 5;
    i = multwoplus1(i);

    return 0;
}
如果我们编译它(并且只查看生成的程序集的相关部分),我们会得到:


如您所见,当
main
调用
multwoplusone
时,它首先将参数(5)放在
$a0
$4
)中
MULTOWPLUSONE
然后将该值左移一位(即乘以二),将结果保存在
$v0
$2
)中,然后在延迟分支槽返回调用方时将其加1。调用方(
main
,在本例中)可以假设返回值将在
$v0
中,如果它愿意,可以使用该值进行处理。

这只是MIPS调用约定
$a
$v
寄存器分别存储函数参数和返回值。但是,您可以按照自己的意愿将它们存储到
$a
$v
$t
中,但由于程序的复杂性,这些寄存器变得杂乱无章。所有寄存器的长度都相同。这意味着$v0和$v1在MIPS32中的大小都是32位,而在MIPS64中的大小都是64位。这似乎是一个愚蠢的问题,但实际上是这样的;sll$2,$4,1#$2是$v0,$4是$a0。。。“1”会接受寄存器$a1吗?
sll$2中的
1
,4,1
是立即数;i、 e.文字值1.为了进一步说明这一点,如果寄存器
$t0
要保存值
0x00008000
,此行对
$t2
有什么影响
slt$t2、$t0、$零应设置为零,因为
0x00008000<0
为假。
multwoplusone:
    sll $2,$4,1  # $2 is $v0, $4 is $a0
    j   $31      # $31 is $ra
    addiu   $2,$2,1

...

main:
    ...

    li  $4,5            # 0x5
    lw  $25,%call16(multwoplus1)($28)
    .reloc  1f,R_MIPS_JALR,multwoplus1
1:  jalr    $25
    nop