0

I'm trying to create a loop that will print if a number given is odd or even (Par). How do I branch the loop when the accumulator value is -1?

START   INP // int(input(""))
        STA n // n =
LOOP    LDA n //
        BRZ END // while n !=0:
        SUB En // n - 1 
        STA n // n = 
        INP // int(input(""))
        ADD sum //
        STA sum //
        BRA LOOP //
END     LDA sum
        OUT
        BRP PO
PO      LDA sum
        BRZ EXIT
        LDA sum
        SUB TO
        STA sum
        BRA PO
ODDE    LDA O
        OTC
        LDA D
        OTC
        LDA D
        OTC
        LDA E
        OTC
O       DAT 79
D       DAT 68
E       DAT 69
        HLT
EXIT    BRP PAR
        HLT
PAR     LDA P
        OTC
        LDA A
        OTC
        LDA R
        OTC 
P       DAT 80
A       DAT 65
R       DAT 82
        HLT
TO      DAT 2
n       DAT 0
sum     DAT 0
En      DAT 1
Par     DAT -1
trincot
  • 317,000
  • 35
  • 244
  • 286

1 Answers1

0

How do I branch the loop when the accumulator value is -1?

The LMC defines mailboxes with values between 0 and 999. They cannot be negative. Even though you can subtract a bigger value from a smaller value, the accumulator's value is then undefined. According to Wikipedia:

SUBTRACT [...] the actions of the accumulator are not defined for subtract instructions that cause negative results - however, a negative flag will be set so that 7xx (BRZ) and 8xx (BRP) can be used properly.

So the only way to reliably detect a negative value is by using BRP: that branch instruction will jump to the provided target address unless a recent subtraction had set the negative flag.

Code review

There are the following issues in your code:

  • Par DAT -1: as stated above, you cannot store -1 in an LMC mailbox. Mailboxes can only store values between 000 and 999.

  • Par versus PAR: you have two labels that only differ in capitalisation. LMC implementations are usually not case sensitive, so this would make those two labels the same. Better use entirely different labels.

  • BRP PO: The label PO points to the very next instruction, so this means that code execution will always continue at that instruction, whether you branch or not. It makes this instruction useless.

  • O DAT 79: this line appears right after a set of instructions that ends with OTC. If ever that code is executed, it will run into this DAT line. That could lead to undefined behaviour. You don't want this to happen. So make sure that DAT mailboxes are shielded from code execution. Add a HLT before a block of DAT to avoid that they are ever executed as if they were code. You have a similar issue at P DAT 80.

  • BRZ EXIT: at the EXIT address, you have a BRP, but as you can only arrive there when the accumulator is zero, the negative flag will not be set, and so BRP will branch always. Note that BRP branches when the negative flag is not set.

  • ODDE: this label is never referenced, and that code block is never executed. You could consider changing the BRA -- that appears just before it -- to a BRP. Then the execution will fall through when the last subtraction led to a negative result (virtually -1 in your case, but the accumulator is undefined).

If you correct all these issues, you'll get to an implementation that will be very close to this working version

trincot
  • 317,000
  • 35
  • 244
  • 286