0
\$\begingroup\$

In my 8080 assembly project I need to check if user entered digits and if so do some stuff on it, otherwise display some error and close app.

Normally i would do it like that

CPI '0';if below '0'
JS ERR
CPI 58D;if over '9'
JNS ERR

but there's no JN and JNS in 8080 instructions, So how can I accomplish this?

\$\endgroup\$
3
\$\begingroup\$

CPI compares an immediate value with the accumulator, by internally using a subtract operation:

In particular, the zero bit is set if the quantities are equal, and reset if they are unequal.

Since a subtract operation is performed, the Carry bit will be set if there is no carry out of bit 7, indicating the immediate data is greater than the contents of the accumulator, and reset otherwise.

(Some notes on usage here: I am using I for the Immediate value, and A for the Accumulator).

  • First comparison: (A < 0) -> ERR

So you are looking for the carry bit to be 1 (I > A) for the first ERR branch. That can be achieved with JC (Jump if Carry).

  • Second comparison: (A > 9) -> ERR

The second CPI wants to see if I < A, which using the same method as above makes things a little tricky. You need to know that the Carry bit is not set (I <= A) and the Zero bit is not set, which gets a little tricky.

JNC performs a Jump if Not Carry, and JZ performs a Jump if Zero. So you want to combine those.

Firstly you know that the Zero bit must not be set under any circumstances. That bit being set would indicate the two values are the same, which is valid. So you can first check that bit to rule it out. Z being set means its a valid entry ('9') regardless of the state of the carry:

JZ GOOD

And then if the Carry bit is not set you can do a JNC to your error routine:

JNC ERR

And finally give it somewhere for the GOOD label t jump to:

GOOD:

So to wrap it all up:

        CPI '0'        ; Compare with '0'
        JC ERR         ; Jump to ERR if Acc < '0'
        CPI '9'        ; Compare with '9'
        JZ GOOD        ; Jump to GOOD if Acc == '9'
        JNC ERR        ; Jump to ERR if Acc > '9'
GOOD:   NOP            ; This is where we end up if it's all valid.

So remember, when doing a CPI you can test for the three things - exactly equal to (Z = 1), Less than (C = 1), and Greater Than or Equal To (C = 0).

If you want to lose some readability, but save a byte or two of program space, you can instead of comparing your upper bound with '9', compare it with '9'+1, which is ':'. That way you're only really interested in the "less than" portion of the CPI, and all others go to ERR:

        CPI '0'        ; Compare with '0'
        JC ERR         ; Jump to ERR if Acc < '0'
        CPI ':'        ; Compare with '9'+1 = ':'
        JNC ERR        ; Jump to ERR if Acc >= ':'
\$\endgroup\$
  • \$\begingroup\$ So why wouldn't you just use CPI ':' (':' is the equivalent of '9'+1), followed by just JNC ERR? \$\endgroup\$ – Dave Tweed Nov 1 '14 at 11:24
  • \$\begingroup\$ You could, but comparing 0-9 is much easier to read afterwards than comparing 0-:, plus it teaches Rotek about how CPI actually works. \$\endgroup\$ – Majenko Nov 1 '14 at 11:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.