MIPS如何存储大于32位的数字?

时间:2018-11-10 15:04:17

标签: assembly memory mips mips32

我一直在寻找答案,但是找不到一个明确的答案。它会在多个寄存器之间分配数字,还是不能简单地应对呢? 我尝试使用MARS进行测试,并使用编号4294967296(即0x100000000),但寄存器仅保存了0x00000000,因此省略了“ 1”位。有没有办法应付这样的数字?

1 个答案:

答案 0 :(得分:2)

使用2个寄存器,高半部使用一个额外的寄存器。 MIPS没有标志,因此没有像其他许多ISA一样使用2指令add / add-with-carry来添加int64_t的方法,但是您可以查看C函数的编译器输出足够容易地将两个64位整数相加。

#include <stdint.h>

int64_t add64(int64_t a, int64_t b) { 
    return a+b;
}

使用gcc5.4 -O3针对MIPS on the Godbolt compiler explorer进行了编译:

add64:
    addu    $3,$5,$7
    sltu    $5,$3,$5     # check for carry-out with  sum_lo < a_lo  (unsigned)
    addu    $2,$4,$6     # add high halves
    j       $31          # return (with a branch-delay slot)
    addu    $2,$5,$2     # add the carry-out from the low half into the high half

在内存中,大端模式的MIPS(MIPS的更常见选择)以大端顺序存储整个64位整数,因此“高半部分”(最高有效的32位)位于较低的地址,因此该字的最高字节位于最低地址,而所有8个字节均按位置值的降序排列。

void add64_store(int64_t a, int64_t b, int64_t *res) { 
    *res = a+b;
}

  ## gcc5.4 -O3 for MIPS - big-endian, not MIPS (el)
    addu    $7,$5,$7        # low half
    lw      $2,16($sp)
    sltu    $5,$7,$5        # carry-out
    addu    $4,$4,$6        
    addu    $5,$5,$4        # high half
    sw      $5,0($2)        # store the high half to res[0..3]
    j       $31
    sw      $7,4($2)        # store the low half to res[4..7]

从使用的寄存器号中可以看到,调用约定在低序号的寄存器(较早的arg)中传递了高半部,这与小端顺序架构中的高半部在后面的arg-pass插槽中。如果您用完了寄存器并且在堆栈上传递了int64_t,这将使事情按预期进行。


在具有标志和随用加指令的体系结构上(例如,例如ARM32),您将获得一条add指令,该指令在C:R0中创建33位结果(进位标志的高位,低32位)在寄存器中。)

add64:
    adds    r0, r2, r0    @ ADD and set flags
    adc     r1, r3, r1    @ r1 = r1 + r3 + carry
    bx      lr

您已标记此MIPS32,因此您没有可用的ISA 64位扩展名(1991年在MIPS III中引入)。我认为某些现代嵌入式MIPS CPU仍仅为32位。 (同样的道理也适用于MIPS64上的128位整数)。