繁体   English   中英

如何在 PC-Spim 中将一个大(64 位)数字除以 2

[英]How to divide a big (64-bit) number by two in PC-Spim

我有一个学校作业,要找出 MIPS 汇编语言中 1 + 2 + ... + n 的总和(使用 PC-Spim 作为虚拟机)。 我写了一个不处理大数字的简单程序(所以n*(n+1)不能大于 2 32 -1 才能工作)。 我今天听说教授,如果你不使用寄存器hilo ,会告诉你使用它们并使程序也适用于 64 位数字!

所以这是最初的程序:

.data
 n:.word 10
 s:.word 0
.text
main:
 lw $t0,n
 add $t1,$t0,1
 mulou $t1, $t0, $t1
 sra $t1,$t1,1
 sw $t1,s
sfarsit:
li $v0,10
syscall

这是我尝试修改它:

.data
 n:.word 1048576
 s:.word 0
 s2:.word 0
.text
main:
 lw $t0,n
 add $t1,$t0,1
 mult $t0, $t1
 mflo $t0
 mfhi $t1
 sra $t0,$t0,1
 sra $t1,$t1,1
 sw $t0,s
 sw $t1,s
sfarsit:
li $v0,10
syscall

如果将sra技巧应用于结果的每个 32 位部分,则它不起作用。 (虽然我希望它会哈哈)

n: 1048576
expected result: 549756338176
what the program gives you: 549755813888

程序结果

我该怎么做才能将大数除以二?

您将两个 32 位数字分别除以 2,而不是一个 64 位数字除以 2。

mult $t0, $t1
mflo $t0
mfhi $t1
sra $t0,$t0,1  # $t0 = $t0 >> 1
sra $t1,$t1,1  # $t1 = $t1 >> 1
sw $t0,s
sw $t1,s

您需要移动整个64 位值。 这意味着较高部分的移出位必须移入较低部分

sll $t2, $t1, 31   # Backup the bit that will be shifted-out
srl $t2, $t1, 1    # High part: $t1 = $t1 >> 1
srl $t0, $t0, 1    # Low part:  $t0 = $t0 >> 1
or  $t0, $t2, $t0  # Merge the shifted-out bit back

由于 n 始终为正数,因此无论如何您都不需要进行算术移位。 将其用作带有srl的无符号类型。 事实上,如果 n 是有符号类型,那么 n/2 会复杂得多,因为您需要在最后进行一些舍入,因为右移向下舍入。 您可以在编译器资源管理器上看到一些演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM