assemblymarie

How can I find even numbers using MARIE?


I'm working on a project but I'm stuck. I'm trying to write a snippet of code that checks if the given number is even by subtracting it by 2 (the given number cannot be more than 6). If it's even it prints a 0, if it's odd it prints a 1.

    int count=input.nextInt()
    int parity=0

    while (count>0)
        count=count-2;
        if (count<0) {
            parity=parity+1;
            System.out.print(parity);
        }
        else if (count==0) {
            System.out.println(parity);
        }

^^ That's my java code that I've tried translating into MARIE language but nothing works.

I'd post my MARIE code but I feel that it's too confusing :/


Solution

  • You only need to check the low bit for 0 / non-zero. Normal architectures have an AND instruction that would make that simple, but MARIE only has add/sub (and compare for greater or less-than).

    But yes, your loop will work, taking O(n) iterations for a number n. It would be a lot easier to implement in asm if you wrote it as a do{}while() loop, like

    n = input;
    do {
        n-=2;      // sub
    }while(n>=0);  // skipcond
    // n==0 or -1 for even or odd
    

    You can do it in O(log(n)) operations by using add as a left shift: AC+AC is the same thing as AC << 1. Do this 15 times to shift the low bit to the top, and the other bits out. (The accumulator, AC, is 16 bits wide).

    This is unfortunately really inconvenient on MARIE, because ADD only works with a memory source operand, not with AC. So you'd have to store AC somewhere so you can use it as a memory source operand for ADD.

    (This is definitely not worth it when you know your input is in the range 0..6. In that case, it only takes at most 3 iterations of the n-=2 loop to get the result, vs. always 15 for this. But with unrestricted inputs, the n-=2 version could need 32768 iterations! Or 16384 if we limit this to positive signed integers; the n-=2 version doesn't even work for negative integers)

    So for example:

    / 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
    

    A loop would make sense, especially if you unrolled it by 2 or something. If AC was only 8 bits, fully unrolling would only take 7 STORE/ADD instructions, but 15 is a bit much.