3

The 8080 is referred to as an 8-bit CPU because it has an 8-bit data bus, but there are a number of cases where it must perform 16-bit memory access, for example when reading or writing a 16-bit register pair, or the 16-bit program counter when performing subroutine call or return.

I assume it supports unaligned access, i.e. the address is not required to be even.

Does it support fully unaligned access in all cases, i.e. no requirement that both bytes be in the same page? For example, if you try to write a 16-bit register pair to address $7fff, will the second byte be written to $8000? Or if the stack pointer was set to $8001 and you perform a subroutine call, will the return address be written to the addresses $8000 and $7fff?

9

TL;DR:

The 8080 does not know about any alignment. All access is byte access and linear. There is also no page logic. All addresses are handled as straight 16 bit and all data access is 8 bit.

(For additional musings see further down)


In Detail:

I assume it supports unaligned access, i.e. the address is not required to be even.

The 8080 does not handle or even know anything about alignment. A 16 bit value is simply stored at two consecutive (8 bit) memory locations.

Does it support fully unaligned access in all cases,

Yes, 16 bit load/stores can be done from any address.

no requirement that both bytes be in the same page?

No, the 8080 does not have a concept of 'pages'. all address pointers are 16 bit and increments are handled as such.

For example, if you try to write a 16-bit register pair to address $7fff, will the second byte be written to $8000?

Yes (*1).

Or if the stack pointer was set to $8001 and you perform a subroutine call, will the return address be written to the addresses $8000 and $7fff?

Exactly.


The 8080 as 16 Bit CPU

Yes, in some sense the 8080 (and its offsprings 8085 and Z80) are 16 bit CPUs - at least when it comes to the register set and address handling. The register file is organzied as

  • a set of six 16 bit register: BC, DE, HL, SP, IP and WZ (*2)
  • directly connected to a 16 bit incrementer/decrementer
  • directly connected to a 16 bit address latch
  • which in turn is connected to the address bus

Thus each of these registers can, within a single machine cycle be

  • latched to be put on the (external) address bus, and/or
  • incremented or
  • decremented

Note that there is no restriction by implied 'pages' or need got even/odd alignment, as address generation is plain 16 bit with a byte sized memory interface.

The 8080s internal structure is, regarding registers and addressing, fully 16 bit, weras the 6502 is here as well 8 bit, operating with separate 8 bit units to handle pages and addresses within pages.


Background

The question may stem from a mixup between data size requirements and data bus size. Alignment issues can only come up with designs that have a finer address granulation than the external data bus and accessing a data item sized of multiple address units, i.e. a CPU with byte addressing but a multiple byte wide data bus accessing data wider than a single byte - like a 68020 (byte addressing, 4 byte wide data bus) accessing a 16 bit word.

The 8080 does not fall into this category. Addressable data unit and access with do not differ.


*1 - Or more correct it will be address 7FFFh and 8000h :)) SCNR

*2 - Note that AF is not one of them A is a separate register, while F doesn't exist.

2
  • 1
    The question may also stem from other 8-bit CPUs (eg 6502) that did have some restrictions on accesses that span a (256-byte) page, due either to specific restrictions (zero page indexed addressing, stack access) or bugs (indirect jump bug).
    – psmears
    Nov 9 '20 at 15:21
  • @psmears Yes, that's exactly what it stems from.
    – rwallace
    Nov 10 '20 at 19:14
4

Although the 8080 and Z80 don't care about alignment, a compiler that targets the 8080 could benefit somewhat from knowing that pointers to 16-bit and 32-bit objects will be aligned. For example, consider the code necessary to process *p += 1; if p is an int*. If p is known to be aligned, a compiler could generate [Z80 opcodes shown]

    ld hl,(p)
    inc (hl)
    jnz noHighByte
    inc l
    inc (hl)
noHighByte:

If a compiler didn't know that p will be 16-bit aligned, it would need to generate an "inc hl" instruction instead of "inc l", which would take an extra two cycles to execute. The extra cost is small enough that none of the 8080/Z80 compilers I've seen made any effort to avoid it, but if a language required that objects be aligned in that fashion it could have offered some benefits.

Interestingly, the benefits would be even larger if small arrays could be guaranteed not to straddle page boundaries, but languages don't offer ways of specifying such constraints. If, e.g., one has a pointer to a char[16]; which is known to be 16-byte aligned, evaluation of p[i]++ could be:

    ld hl,(p)
    ld a,(i)
    add a,l
    ld  l,a
    inc (hl)

instead of something like either:

    ld hl,(p)
    ld a,(i)
    ld e,a
    ld d,0
    add de,hl
    inc (hl)

or

    ld hl,(p)
    ld a,(i)
    add a,l
    ld  l,a
    jnc noCarry
    inc h
noCarry:
    inc (hl)

with the latter version being bigger, but leaving DE unaffected. Note that the last version is bigger than the middle one, but faster, since "ADD HL,DE" is a very slow instruction.

In order to exploit things like the latter speed up, a compiler would have to know that indexing p by i wouldn't cross a page boundary, and no languages I know of would generally provide any way of telling a compiler that.

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.