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

小狐

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

彼得·科德斯

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

#include <stdint.h>

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

使用 gcc5.4 1在 Godbolt 编译器资源管理器上为 MIPS编译-O3 -fno-delayed-branch

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
    addu    $2,$5,$2     # add the carry-out from the low half into the high half
    j       $31          # return
    nop                # branch-delay slots

脚注 1:所以 GCC 只用 NOP填充分支延迟槽,而不是真正的指令。因此,相同的代码可以在没有延迟槽的简化 MIPS 上运行,如默认情况下 MARS 模拟。


在内存中,大端模式下的 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] (byte offsets)
    sw      $7,4($2)        # store the low  half to res[4..7]
    j       $31
    nop                   # delay slot

从所使用的寄存器编号可以看出,调用约定在较低编号的寄存器(较早的 arg)中传递高半部分,这与小端架构不同,在小端架构中,高半部分在后面的 arg-passing slot 中。如果您用完寄存器并且int64_t在堆栈上传递了一个,这会使事情按预期工作


在具有标志和带进位加法指令的体系结构上(例如 ARM32),您会得到一条加法指令,该指令可创建 33 位结果C:R0(进位标志中的最高位,寄存器中的低位 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引入,但对于嵌入式使用,MIPS32 是现代 MIPS,具有除 64 位寄存器之外的扩展。

相同的推理适用于 64 位 MIPS 上的 128 位整数 daddu

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

超过32位的MIPS乘法

来自分类Dev

32位整数数组的MIPS指令

来自分类Dev

如何在32位C ++中打印大于2 ^ 32的数字?

来自分类Dev

如何在32位C ++中打印大于2 ^ 32的数字?

来自分类Dev

无法在MIPS上添加两个32位数字

来自分类Dev

如何从32位数字中提取位

来自分类Dev

如何从32位数字中提取位

来自分类Dev

用于 32 位 MIPS 处理器的 Cmake 工具链

来自分类Dev

生成一个随机的32位数字以存储在64位寄存器中

来自分类Dev

如何在javascript中将双精度(64位)数字转换/存储为32位浮点数或UInt16

来自分类Dev

如果库具有32位限制,如何在Arduino上输出64位数字?

来自分类Dev

如何使用32位计算机在PHP中打印40位数字

来自分类Dev

C ++如何在32位数字中更改4位的值

来自分类Dev

如何在32位ARM处理器中加载64位数字?

来自分类Dev

位操作和> 32位数字?

来自分类Dev

MIPS 32 ORI参数

来自分类Dev

如何从main()返回大于8位的数字?

来自分类Dev

我如何存储大于100亿的数字

来自分类Dev

在C ++中,如何将32位数字传递给'int'变量,而不会将大于0x7FFFFFFF的值视为负数?

来自分类Dev

从mips中的现有寄存器值创建新的32位值

来自分类Dev

从mips中的现有寄存器值创建新的32位值

来自分类Dev

如何通过命令行获取32位十六进制数字的随机字符串?

来自分类Dev

如何数学上获得带符号的32位整数位置值数字?

来自分类Dev

如何在Java和PostgreSQL中处理32位数字?

来自分类Dev

如何知道在ARM中某个数字可以表示为32位立即数?

来自分类Dev

分配大于32位的堆内存允许

来自分类Dev

32位数字的反向乘法

来自分类Dev

Java无法处理32位数字

来自分类Dev

C中32位数字的乘法

Related 相关文章

热门标签

归档