编写一个 MIPS 程序来测试一个数是否是 2 的幂

Write a MIPS program that tests if a number is a power of two

编写一个 MIPS 程序来测试一个数是否是 2 的幂。在 SPIM 中将寄存器 $t0 设置为某个值,并将其用于测试 2 的幂。该程序将在控制台中生成输出。

35 不是二的幂

256 是 2 的幂。

到目前为止,我有这个

    .data

    spc1:   .asciiz " "
    nl:     .asciiz "\n"
    tb:     .asciiz "\t"
    msg1:   .asciiz "is not a power of two."
    msg2:   .asciiz "is a power of two."

    .text    # "text section" code and read-only data

    .globl main # declare `main' as a global symbol

    main:   #sra $t1, $t0, 1
    li $t1, 1
    loop:   beq $t0, $t1, end
    sra $t0, $t0, 1
    j loop
    end:    la $a0, msg2
    li $v0, 4
    syscall
    addi $v0, [=10=], 10
    syscall

我在模拟器中设置了 $t0,这样就可以正常工作了。但无论我将其设置为多少,我都会得到 "is a power of two"。我正在使用左移,但这一直给我错误的答案。如何正确使用shift来回答这个问题?

$t1 初始化为 1 后,您应该在每次循环迭代中对 $t1 进行左移。在每次循环迭代中,$t1 寄存器将等于 2 的新幂。

如果 $t1 等于 $t0,您应该跳出循环。这是 $t0 是 2 的幂的情况。如果 $t1 左移后变为 0,则 $t0 不是 2 的幂。

有一种更简单的方法来测试一个数是否是 2 的幂。在 C 伪代码中:

bool is_power_of_two(unsigned int number) {
    return (number & (number - 1)) == 0;
}

这是可行的,因为 2 的幂将具有 000…010…0 形式的二进制表示,而比它小一的数将具有 000…001…1 形式的二进制表示。也就是说,2 的次方正好设置了一位,而比它小的数在该组之前的每一位都有。结果,这些数字之间的按位与将为零,因为它们没有共同的设置位。每隔一对连续的数字将共享一些共同的设置位,因此它们之间的按位与不会为零。

(注意这个算法会告诉你1是2的次方,这是正确的:2的0次方就是1!)

由于这显然是 class 作业,我会让您自己将其转换为 MIPS 代码。 :)