Question

Something that has always confused me is how 8-bit computers access more than 256 bytes of RAM. I know that it must use two registers, but can any one show me an example of what this would look like in assembly code?

Like:

mov a, [x]   ???
Was it helpful?

Solution

Let's imagine we have LOWER and HIGHER 8bit half of the address in registers L and H. For example, we want to read byte from address 32770 dec = 8002 hex.

mov l, 02h  ;lower byte of address
mov h, 80h  ;higher byte of address
mov a, [hl] ;a <-- [h*256 + l]

Many addressing modes exist in CPUs. So we can have a different example, e.g. with just a single register and an immediate address:

mov h, 80h
mov a, [2]  ;a <-- [h*256 + immediate]

It always depends on a particular CPU architecture. For example Zilog Z80 is called 8-bit CPU but it also contains many 16-bit instructions. You can do indexed addressing on it like this:

mov ix, 8002h  ;base address of an array
mov a,[ix+20]  ;a <-- [ix + 20] i.e. read a byte from an array like ix[20] in C

Note: Those old 8-bit CPU's use an 8-bit accumulator, i.e. they can compute math and other arithmetic stuff only in an 8-bit register, so they are 8-bit on a software computation level. And their memory accessing unit is 8-bit, i.e. it can read or write just a single byte of memory at a time, so they are 8-bit on hardware level too. Those 16-bit instructions are slow, they actually do a pair of 8-bit operations in succession.

OTHER TIPS

Let's consider the 8080 (Z80, etc.) it had 8-bit registers, but could pair the registers to act like 16-bit registers. Probably the most-used pair was HL, which was H for the 8 high bits and L for the 8 lower bits of an address. The other register pairs were BC and DE -- again, most instructions worked with only one register of the pair at a time, but a few could use the pair together to work with 16-bit quantities (e.g., at least if memory serves, there was one to add DE to HL).

Some instructions could also use 16-bit addresses directly:

jmp 01234h

The 6502 was sort of the same way, but it restricted some instructions to working with the first 256 bytes of RAM (aka "Page 0"). Later versions (65816?) did support picking different physical addresses that would be treated as page 0 though.

There are lots of techniques to achieve this

The Intel 8080 is an 8-bit CPU with 2 registers H and L for indirect address, allowing it to address 16-bit of memory. The 16-bit 8086 has 20 bit address with segmentation. 80286 uses 24-bit address with the high 16-bit segment is an index into a table of segment descriptors. The 32-bit x86 uses 36 bit address with PAE...

PIC microcontrolers have 8-bit value in registers merge with the high bits in PC (or some dedicated address register, as I don't remember) to form 13-bit address (or more, depend on architecture)

Another common way in microcontrollers (some microprocessor architectures) is banking, in which you change the "memory window" that the CPU can see each time.

  • Intel 8051 has 4 register banks with the common one always visible and the rest can be selected by a bank switching instruction. Some version can use banking for the code address, extend it to 2MBs of code.
  • DOS uses memory banking in EMS and XMS to map higher memory to lower addresses in order to access more than 1MB or RAM.
  • 32-bit Windows uses Address Windowing Extensions in PAE mode to allow 32-bit processes to access more than 2GB of RAM

For more information you can read here

The 6502 had indexed memory read instructions lda $01200,Y and lda $1413,X where the 16-bit address was encoded as part of the instruction. At any time, that kind of instruction saw a window of 256 bytes. In order to access the next 256 bytes, the instruction itself was modified to read lda $1300,Y for example.

Then 8086 had segmented architecture, where every memory access is coupled with implicit or explicit segment register. mov reg,[bp] and push/pop are associated with stack segment ss, [rep] movs are associated with ds:[si], es:[di]; Program counter / jumps are associated with code segment cs.

The physical address is in 8086 mode calculated as stack_reg * 16 + offset, where trying to read a word at seg_reg:[ffff] causes an segment violation exception.

VGA graphics in 8086 architecture was implemented with memory mapping a 64k segment to ISA-bus. Also by programming the Hardware through in / out instructions, it was possible to select a different 64-k page at the graphics board. Thus it was possible to advance beyond 320x200 x 256 color VGA limitation to 640x480 SVGA.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top