我正在编写 ac 程序并解码 mips 32 位指令并模拟它们的功能减去按位部分。我不知道我应该如何在这里区分签名和未签名的操作。
例如,给定寄存器 rd 和 rs,我需要相乘并将结果放入 rd。
对于多指令,它就像这样简单:
reg[rd] = reg[rs] * reg[rt];
多指令应该是什么?我需要先对寄存器的内容进行按位运算吗?
我还需要这样做:
-add,addu,-div,divu -sub,subu
它们在功能上的区别是否相同?
MIPS 乘法不能溢出。它是具有完整 64 位结果的 32x32 位操作。
有符号和无符号结果之间也存在显着差异。
要在 C 中轻松模拟这些,您需要来自以下位置的 C99 整数类型<stdint.h>
:
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);
mips 程序集中的 IIRC 有符号和无符号变体之间的唯一区别是它们是否设置了溢出标志。那么,multu 更容易实现。对于常规的有符号的 mult,您需要确定它是否会溢出目标寄存器并设置标志。