-4
input a number and store it in x
input a number and store it in y
while x < 10 do
x =x +1 
 output value of x;
end while
output the value of y*2
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847

1 Answers1

2

While statements translate into assembly language using if-goto-label.  We can illustrate that using C:

while ( x < 10 ) {
    x++;
    print(x);
}
...

becomes:

loop1:
    if ( x >= 10 ) goto loop1Done;    // this is a conditional branch
    x++;
    print(x);
    goto loop1;                       // this is an unconditional branch
loop1Done:
    ...

Notice that in the if-goto-label style, the condition x < 10 is reversed to x >= 10 b/c we want to exit the loop on this condition, whereas the C while statement tells us when to continue the loop.  Because these two senses (C while vs. C if-goto-label) are opposite, we choose the negation of x < 10, which is x >= 10, to exit the loop.


Corresponding to C's goto statement, MARIE uses a Jump assembly instruction for unconditional branching.

Corresponding to C's if-goto construct, MARIE uses conditional skips for conditional branching: the Skipcond instruction is used in a multi-instruction sequence.

The Skipcond compares the AC, the accumulator register, against zero, and either allows the next instruction to execute, or not by skipping over and past it — when it skips, it skips exactly 1 instruction: no more, no less.  Usually the next instruction is a Jump used to change the flow of control (it doesn't have to be a jump, it can be any other single instruction that you want to conditionally skip).

To accomplish a conditional branch (an if-goto), we combine the conditional skip instruction, Skipcond, with the unconditional branch instruction, Jump.  Because we tell Skipcond when to skip, it will only branch when Skipcond doesn't skip.  Thus, we negate the condition from the if-goto-label form:

if ( x >= 10 ) goto loop1Done;

becomes:

Skipcond 000                 // Skip the Jump if AC < 0
Jump loop1Done               // Jump may or may not fire, depending on prior Skip

For an example in larger context, take the statement:

if ( x >= 10 ) goto loop1Done;

Because the skip/jump sequence makes us negate from if-goto-label form (and for a second time, if you started with C), we want to set up x < 10 in the Skipcond; Jump sequence.

First we apply some basic math: x - 10 < 0, subtracting 10 from both sides of the relational operator, <, preserves the logic of x < 10 (modulo overflow).  Now we have an expression that compares to zero, and that is appropriate for what MARIE's Skipcond can do for us.

loop1,                
       // if ( x >= 10 ) goto loop1Done;
       load X         // AC = x
       Subt Ten       // AC = x - 10
       Skipcond 000   // MARIE will skip the next instruction if AC < 0, i.e. x < 10
       Jump loop1Done // Will only fire if AC >= 0, i.e. x >= 10

       // x++;
       Load X         // AC = x
       Add One        // AC = x + 1
       Store X        // x = AC

       Output         // outputs the AC (note that the AC == x here)

       Jump loop1     // continue the loop
loop1Done,            // end of loop, on to next statement after
        ...

        // Variables & Constants
X,      Hex 0
Ten,    Dec 10
One,    Dec 1

In summary, we can translate any control structure from structured statement form into assembly form using if-goto, goto, and labels.  Structured statements translate quite literally using patterns like these, even when the structured statements are nested (nesting doesn't change the replacement pattern).

On MARIE, we can compose the if-goto operation from a skipcond/jump pair of instructions.  In order to use the skipcond/jump pair we need to compute a value relative to 0 into the AC (i.e. x-10).


Complicating matters on MARIE, Skipcond does not have all the general purpose relations: <, <=, ==, !=, >=, >.  MARIE only has <, ==, and > — they cannot be combined in one instruction to form <= or >=.

Sometimes we need to do an if-goto using one of the relational operators that Skipcond won't directly do for us (so, yes, we get to reverse the condition yet again).

First, let's see a general purpose way to use the opposite condition in if-goto-label:

    if ( x >= 10 ) goto label1;         // goes to label1 if x >= 10
    ...                                 // comes here otherwise, i.e. x < 10

    if ( x < 10 ) goto uniqueNewlabel;  // goes to uniqueNewLabel if x < 10
    goto label1;                        // goes here (which jumps to label1) if x >= 10
uniqueNewlabel:                         // comes here if x < 10

The latter just above swaps the use of the < relational for the >= relational found in the original if-goto to accomplish the same control flow logic.  Btw, this transformation also works in the reverse, so if you have the latter, it can be transformed into the former.

Ok, now that we have a method to invert the operation we need, we can apply it to MARIE's Skipcond sequence.  Let's say we really need the following:

    if ( x < 10 ) goto somewhere;

In a hypothetical variation on MARIE, that might translate to

    Skipcond >=           // skips the succeeding Jump on >=
    Jump somewhere        // goes here on <, so executes the Jump

But there is no Skipcond for >=.  We'll use the above pattern substitution to reverse >= into <, which MARIE does have:

    Skipcond 000             // < that MARIE does have
    Jump uniqueNewLabel      // fires only when >=, so used to "skip" the next line
    Jump somewhere           // desired target for when <
uniqueNewLabel,

There are other patterns to change the sense of tests as well.

    if ( x < 10 ) goto somewhere;

Is logically equivalent (on the integers) to:

    if ( x <= 9 ) goto somewhere;

Having swapped use of < for <=, we can again use MARIE's Skipcond/Jump two instruction pair for this if-goto.

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53