3

I want to branch if x-y overflows.

I came up with idea to store x-y into register A , store 0 into register B and compare these two registers.

Unlike 8086, 8080 doesn't have an OF flag or jo / jno instructions.

x db
y db

    lda x
    mov b,a
    lda y
    sub b
    mvi b,0
    cmp b
    jp overflow

notOverFlow HLT
overflow HLT    

It works with x=128 , y=127 but not with values x=0, y=0.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
P. Bolfa
  • 99
  • 1
  • 7
  • Does 8080 have an overflow flag that `sub` sets? 8086 has an `OF` flag for signed overflow (and a CF flag for unsigned wraparound), so you can just `sub` / `jo overflow` (i.e. just do it and jump if it *did* overflow. You can always `add b` to undo in the `overflow` code path). See http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt for more details about what overflow and carry actually are. – Peter Cordes Nov 09 '17 at 16:32
  • Oh, you mean you can't use `jo` because 8080 doesn't have a `jo` instruction or an OF flag. https://en.wikipedia.org/wiki/Intel_8080#Flags. That would have been clearer. – Peter Cordes Nov 09 '17 at 16:40
  • I assume you want signed arithmetic, since for unsigned `CF` works already. Emulating `OF` yourself based on the sign bits of `x`, `y` and the result is not terribly difficult. Subtracting operands with same sign can not overflow and otherwise the result should have the same sign as `x`. `OF = X7 & !Y7 & !R7 | !X7 & Y7 & R7` – Jester Nov 09 '17 at 17:22
  • The Z80 uses the P bit to signify overflow for ALU instructions... but the 8080 doesn't; it's one place where the Z80 isn't backwards-compatible. Instead the P bit signifies parity, which is nigh-useless. – David Given Feb 11 '19 at 20:58
  • Possible duplicate of [How do I efficiently do signed comparisons on the 8080?](https://stackoverflow.com/questions/54639771/how-do-i-efficiently-do-signed-comparisons-on-the-8080) – phuclv Feb 12 '19 at 11:09

1 Answers1

1

If no overflow means the arithmetic result is representable as an 8-bit signed value, then the following rules should apply:

  • if y = 0, then no overflow.
  • if y > 0, then overflow if truncate(x - y) > x.
  • if y < 0, then overflow if truncate(x - y) < x.

Here truncate(x) means the truncated 8-bit signed value of x.

Then the code may look like this:

    lda y       ; Load y.
    mov b, a

    lda x       ; Load x.
    mov c, a

    sub b       ; No overflow if truncate(x - y) = x, that is, y = 0.
    cmp c
    jz no_overflow

    jm else     ; Jump if truncate(x - y) < x.

                ; At this point y != 0 and truncate(x - y) > x.

    mov a, b    ; Overflow if y > 0.
    ana a
    jp overflow

no_overflow:
    ...

                ; At this point y != 0 and truncate(x - y) < x.
else:
    mov a, b    ; Overflow if y < 0.
    ana a
    jp no_overflow

overflow:
    ...

As an optimization measure, the two mov a, b instructions can be replaced with a single mov a, b just before jm else.

Ivan Kosarev
  • 304
  • 1
  • 7