【问题标题】:difference between mult, multu simulating in cc语言中的多,多仿真之间的区别
【发布时间】:2013-09-29 01:15:14
【问题描述】:

我正在编写一个 c 程序并解码 mips 32 位指令并模拟它们的功能减去按位部分。我不知道我应该如何区分签名和未签名的操作。

例如,给定寄存器 rd 和 rs,我需要将结果相乘并将结果放入 rd。

对于多指令,就这么简单:

reg[rd] = reg[rs] * reg[rt];

多指令应该是什么?我需要先对寄存器的内容进行按位运算吗?

我还需要做:

-添加,添加, -div,迪武 -sub, subu

它们在功能上的区别是否相同?

【问题讨论】:

    标签: c assembly mips


    【解决方案1】:

    MIPS 乘法不能溢出。它是一个 32x32 位的运算,具有完整的 64 位结果。

    有符号和无符号结果之间也存在显着差异。

    要在 C 中轻松模拟这些,您需要来自 <stdint.h> 的 C99 整数类型:

    uint32_t reg1, reg2; /* Use this type for the registers, normally */
    uint32_t hi, lo; /* special MIPS registers for 64-bit products and dividends */    
    /* Signed mult instruction: */
    int64_t temp = (int64_t)(int32_t)reg1 * (int_64_t)(int32_t)reg2;
    hi = (uint32_t)((temp>>32) & 0xFFFFFFFF);
    lo = (uint32_t)(temp & 0xFFFFFFFF);
    

    已完成到有符号 32 位类型的中间转换,以便转换为有符号 64 位类型将在乘法之前进行符号扩展。无符号乘法类似,只是不需要中间转换:

    /* Unsigned multu instruction: */
    uint64_t tempu = (uint64_t)reg1 * (uint64_t)reg2;
    hi = (uint32_t)((temp>>32) & 0xFFFFFFFF);
    lo = (uint32_t)(temp & 0xFFFFFFFF);
    

    【讨论】:

    • @WillLarche 这可能是偏执和不必要的,但按位和确实保证了 64 位值完全等于它被转换成的 32 位值。无论发生什么其他情况,标准都要求在这种情况下保留原始值。如果先前的值在新类型中完全可以表示,那么它必须是转换后的值。
    【解决方案2】:

    mips 汇编中的 IIRC 有符号和无符号变体之间的唯一区别是它们是否设置了溢出标志。那么,multu 更容易实现。对于常规的、有符号的、mult,您需要确定它是否会溢出目标寄存器并设置标志。

    【讨论】:

      猜你喜欢
      • 2014-07-24
      • 1970-01-01
      • 2018-10-08
      • 2018-09-12
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      • 2021-06-07
      • 2014-11-03
      相关资源
      最近更新 更多