我正在编写一个c程序并解码mips 32位指令并模拟它们的功能减去按位部分。我不知道如何在这里区分有符号和无符号操作。
例如,给定寄存器rd和rs,我需要乘以并将结果放入rd。
对于mult指令,它就像这样简单:
reg[rd] = reg[rs] * reg[rt];
multu指令应该是什么?我是否需要首先对寄存器的内容进行按位操作?
我还需要这样做:
-add,addu, -div,divu -sub,subu
它们在功能上的区别是什么?
答案 0 :(得分:2)
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);
答案 1 :(得分:1)
IIRC in mips程序集中有符号和无符号变体之间的唯一区别是它们是否设置了溢出标志。那么multu更容易实现。对于常规的,有符号的mult,你需要确定它是否会溢出目标寄存器并设置标志。