您只需要检查低位是否为 0 / 非零。普通架构有一个 AND 指令可以让这变得简单,但MARIE 只有加/减(并比较大于或小于)。
但是,是的,您的循环将起作用,对 number 进行 O(n) 次迭代n
。如果你把它写成一个do{}while()
循环,那么在 asm 中实现会容易得多,比如
n = input;
do {
n-=2; // sub
}while(n>=0); // skipcond
// n==0 or -1 for even or odd
您可以在O(log(n))
操作中使用add
as 左移来执行此操作:AC+AC
与AC << 1
. 这样做 15 次以将低位移到顶部,并将其他位移出。(累加器AC 为 16 位宽)。
不幸的是,这对 MARIE 来说真的很不方便,因为ADD 仅适用于内存源操作数,而不适用于AC
. 因此,您必须将 AC 存储在某处,以便可以将其用作 ADD 的内存源操作数。
(当您知道您的输入在 0..6 范围内时,这绝对不值得。在这种情况下,最多只需要n-=2
循环 3 次迭代即可获得结果,而对此始终需要 15 次。但不受限制输入,该n-=2
版本可能需要 32768 次迭代!如果我们将其限制为正符号整数,则为 16384;该n-=2
版本甚至不适用于负整数)
例如:
/ Assuming input in AC
Store tmp
Add tmp
Store tmp
Add tmp
/ repeat this 13 more times, for a total of 15 ADDs
/ inconvenient to make a loop because Marie only has 1 register
/ but would be smaller for this many shifts
/ AC = input << 15
/ AC is non-zero for odd, zero for even. You could just store that directly if you want.
/ If you want to branch on it here, or in some code that reloads that 0 / non-zero result
SkipCond 400 / jump over next insn if AC==0
jump odd_input / or this can be a store instruction
/ else fall through when input was even: input&1 == 0
tmp, dec 0
一个循环是有意义的,特别是如果你将它展开 2 或其他东西。如果 AC 只有 8 位,完全展开只需要 7 条 STORE/ADD 指令,但 15 条有点多。