我写了一个代码来检查一个数字是偶数还是奇数,但我的程序包含一个无限循环,我真的找不到它。
以下是 ISA 中的所有命令:
命令第 1
部分 命令第 2 部分
这是我的代码:
#Read in Number
addi zero t0 1
sysmove exc t0
syscall
#Copy Number to a0
sysmove a0 I[0]
#check if number is even or odd
ldd t1 zero 0
ldd t2 zero 0
ldd t3 zero 1 #Register contains 1
ldd t4 zero 0 #Register contains 0
#divide:
subi a0 t2 2 # subtract with 2
ldd t2 a0 0 #move to a0
beq a0 t3 odd #compare a0 with 1
beq a0 t4 even #compare a0 with 0
jmp 6
#odd:
cout odd
syscall
#even:
cout even
syscall
偶数与奇数由最低位(即最低有效位(决定。 如果为 0,则数字为偶数,否则(为 1 且(该数字为奇数。
通常,可以使用具有常量掩码1的简单AND即时操作来隔离该单个位,这将使除LSB以外的所有其他位归零。 如果您没有 AND 即时,但有 AND,则可以将立即 1 值加载到寄存器中并执行(非立即(AND。
1111110000000000
5432109876543210 bit position
----------------
abcdefghijklmnop word of interest (to test for even odd)
note that bit "p" tells us even vs. odd
0000000000000001
&
----------------
000000000000000p
但是,如果没有 AND 操作,还有许多其他方法可以隔离单个位(或位范围(。 这是其中之一:
向左移动,直到它是唯一剩余的位。 左移将删除更高重要性的位,同时以零移位。 因此,如果您的计算机使用的是 16 位寄存器,则左移 15 将产生以下值:
abcdefghijklmnop word of interest (to test for even odd)
note that bit "p" tells us even vs. odd
<< 15
----------------
p000000000000000
当寄存器为零时,p为零,表示数字是偶数,当非零时,p为非零,因此该数字是奇数。
如果我们只向左移动一点,我们会得到
abcdefghijklmnop word of interest (to test for even odd)
note that bit "p" tells us even vs. odd
<< 1
----------------
bcdefghijklmnop0
因此,如果我们做同样的班次 15 倍,我们就会得到p000...
.
您应该能够使用shli r1, r2, 15
.
如果您愿意,可以采用该左移值并将其向右移动。 使用算术右移,结果将是:
p000000000000000
>> 15 arithmetic shift
----------------
pppppppppppppppp
算术移位适用于提取有符号字段。 (当然,我们很少看到一位有符号字段,因为 1 位有符号字段只能表示 -1 和 0!
通过逻辑右移,结果将是:
p000000000000000
>> 15 logical shift
----------------
000000000000000p
此结果将低位恢复到其先前的位置(并给出与 AND 相同的答案,立即为 1(。 (但是,我们不需要仅仅为了针对 0 对其进行测试而将位p
返回到其原始位置。
如果您想要无损班次,旋转说明很方便。 这些在 CPU 寄存器较差的计算机上特别有用,因为在某些情况下,无损移位不需要额外的寄存器来保留原始位。 但是对于位或字段的提取,我们需要一个有损操作, 松散或剥离位,以便轮班完成工作。