MARIE 中的 SKIPCOND 用于循环或条件

SKIPCOND in MARIE for looping or conditionals

我必须用 MARIE 汇编语言实现这个伪代码

Input a number and store it in X;
Input a number and store it in Y;
while X < 10 do
X = X + 1;
Output the value of X;
endwhile;
Output the value of Y*2;

到目前为止,我已经写了这个:

Input
Store X
Input
Store Y

Loop, Load X
Subt TEN
Skipcond 400
Jump Endloop
Load X
Add ONE
Store X
Output

(然后我不确定如何将 Y 与 2 相乘)

X, Dec 0
Y, Dec 0
ONE. Dec 1
TEN, Dec 10

我使用的 skipcond 指令是否正确?

Skipcond 是相当有限的。首先,它只能跳过一条指令,其次,它只能测试 6 个必要条件中的 3 个。 Skipcond 可以跳过 <、= 和 >,但不能跳过 <=、<> 或 >=。 (这些也是已签名的条件,没有未签名的测试,但这是另一回事。)

如果您可以在一条指令中做一些有用的事情,那么 SkipCond 可以提供帮助。

首先,我们应该注意 C 中的 if-then 在汇编中需要相反的条件,因为在 C 中我们说什么时候 运行 then-部分,但在汇编中我们说何时不 运行 一条指令(即何时跳过一条指令)。因此,如果您可以在一条指令中做一些有用的事情,您可以编写一个 if-then 来测试 >=、<>、<=,但不测试其他条件。对于那些,请提前阅读以了解如何将 SkipCond 与 Jumps 结合使用。

cond Skips when
Skipcond 000 AC < 0
Skipcond 400 AC = 0
Skipcond 800 AC > 0

如果您需要某些东西 (a) 需要比 then 部分更多的指令,或 (b) 需要其他条件测试之一,或 (c) 是更复杂的控制结构,例如 if- then-else 那么我们有时可以将 SkipCondJump 结合使用(就像你经常做的那样):

Skipcond xxx
Jump Label
cond Skips when Jumps to Label when
Skipcond 000 AC < 0 AC >= 0
Skipcond 400 AC = 0 AC <> 0
Skipcond 800 AC > 0 AC <= 0

但是,由于 MARIE 只能执行 6 个必要的关系运算符中的 3 个,有时我们将不得不引入一个包含 2 个 Jumps.

的 3 指令序列

下面的构造将根据上面的表格跳转到 Around — 然而,Around 在这里设置为 绕过另一个跳转 ,并且基本上保持当前的代码序列,而第二个 Jump 转到 Label (尽管现在在相反的 Skipcond 情况下,它选择了其他 3 个关系运算符)。

    ..
    Skipcond xxx
    Jump Around     # this Jump is executed if AC >= 0, AC <> 0, AC <=0, respectively
    Jump Label      # this Jump is executed if AC < 0, AC = 0, AC > 0, respectively
Around:
    ....
cond Skips When Jumps "Around" Jumps to Label
Skipcond 000 AC < 0 AC >= 0 AC < 0
Skipcond 400 AC = 0 AC <> 0 AC = 0
Skipcond 800 AC > 0 AC <= 0 AC > 0

如果您打算执行 if-then-else,另一种方法可以反转条件并交换 then-part 和 else-part — 有时可以使用更简单的 2 指令序列。

虽然这些不是 SkipCond 的唯一用途,但它们确实涵盖了所有 6 个关系运算符,并提供了一个通用的 if-goto-label,它是汇编语言中控制结构的基石。


对于原题post:你关于跳过Jump指令的想法是正确的,但条件是错误的。

好的,现在你正在做的是这个伪代码:

..
while X < 10 do
    X = X + 1;
    Output the value of X;
endwhile;
....

我们先把这段伪代码翻译成汇编语言的if-goto-label风格。 (这是有效的 C 代码,仅供参考,因此您可以使用实际语言编写、测试和调试您的 if-goto-label 伪代码。)

..
Loop:
    if ( X >= 10 ) goto Endloop;
    X++;
    output(x);
    goto Loop;
Endloop:
....

让我们注意,C 语言中 while 条件的意义是说什么时候继续循环,而对于 if-goto-label,我们在这里说的是什么时候退出。因此,循环条件的含义是相反的(C while 与 if-goto-label)。从逻辑上讲,在 if-goto-label 中,我们在 C-while 条件为假时分支(退出)——并且由于条件是关系运算符,我们可以通过翻转关系运算符来否定条件。 (注意:意义的分歧并不总是如此;C 的 do-while 和循环末尾的 if-goto-label 向后分支在意义上一致:两者都在条件为真时继续循环并在条件为假时退出.)

接下来,b/c MARIE 不进行除零以外的比较,让我们应用一些数学运算:从 X >= 10 到 [=42] 的 >= 表达式两边减去 10 =]

..
Loop:
    if ( X - 10 >= 0 ) goto Endloop;
    X++;
    output(x);
    goto Loop;
Endloop:
....

现在你可以从与零的比较和上面的表格中看出你应该在这里使用什么条件。

或者,我们可以使用调试器来帮助我们查看它是否正常工作(如果不起作用,则使用不同的条件)。