assemblyconditional-statementspseudocodemarie

SKIPCOND in MARIE for looping or conditionals


I have to implement this pseudocode in MARIE assembly language

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;

So far, I have written this:

Input
Store X
Input
Store Y

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

(And then i am not sure how to multiply Y with 2)

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

Am i using correct skipcond inetruction?


Solution

  • Skipcond alone is quite limited.  First, it can only skip one instruction, and second, it can only test 3 of the necessary 6 conditions.  Skipcond can skip on <, =, and >, but cannot skip on <=, <>, or >=.  (These are signed conditions, as well, there's no unsigned tests, but that's another matter.)

    If you can do something useful in one instruction, then here's how SkipCond can help.

    First, we should note that an if-then in C requires the opposite condition in assembly, because in C we're saying when to run the then-part, but in assembly we're saying when not to run that one instruction (i.e. when to skip an instruction).  So, if you can do something useful in one instruction, you can write an if-then that tests for >=, <>, <=, but not the other conditions.  For those, read ahead to see how to combine SkipCond with Jumps.

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

    If you need something that (a) requires more instructions than one for the then-part, or (b) needs one of the other condition tests, or (c) is a more complicated control structure such as if-then-else then we can sometimes use SkipCond combined with Jump (as often done and as you are doing):

    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

    However, since MARIE can only do 3 of the 6 necessary relational operators sometimes we will have to introduce a 3-instruction sequence involving 2 Jumps.

    The following construct will jump to Around according to the above tables — however, Around is set up here to jump around the other jump, and basically stay with this current sequence of code, whereas the 2nd Jump goes to Label (though now in the opposite Skipcond cases, which picks up the other 3 relational operators).

        ..
        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 your intent is to do an if-then-else, another approach can be invert the condition an also swap the then-part and the else-part — that can sometimes allow use of the simpler 2 instruction sequence.

    While these are not the only uses of SkipCond, they do cover all 6 relational operators, and provide a general purpose if-goto-label which is the cornerstone of control structures in assembly language.


    For the original question post: you have the right idea about skipping a Jump instruction, but the wrong condition.

    Ok, now what you're doing is this pseudo code:

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

    Let's first translate this pseudo code into the if-goto-label style of assembly language.  (This is valid C code, fyi, so you can write this, test & debug your if-goto-label pseudo code in an actual language.)

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

    Let's note that the sense of the while-condition in C says when to continue the loop, whereas with if-goto-label, we are here saying when to exit.  Thus, the senses of the loop conditions are reversed (C while vs. if-goto-label).  Logically, in if-goto-label, we branch (to exit) when the C-while condition is false instead — and since the condition is a relational operator we can negate the condition by flipping the relational operator.  (Note: Disagreement of the sense is not always the case; C's do-while and an if-goto-label backward branch at the end of the loop agree in sense: both continue the loop on condition being true and exit on condition being false.)

    Next, b/c MARIE doesn't do comparison except against zero, let's apply some math: subtract 10 from both sides of the >= expression from X >= 10 to X - 10 >= 0

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

    Now you can see from the comparison to zero and the above tables what condition you should use here.

    Alternatively, we can use the debugger to help us see if it is working (and use a different condition if that doesn't work).