Segments and Offsets

Pay close attention, because this topic is (I believe) the single most difficult (or annoying, once you understand it) aspect of ASSEMBLER.

An OverView:

The original designers of the 8088, way back when dinasaurs ruled the planet, decided that no one would ever possibly need more than one MEG (short for MEGABYTE :) of memory. So they built the machine so that it couldn't access above 1 MEG. To access the whole MEG, 20 BITs are needed. Problem was that the registers only had 16 bits, and if the used two registers, that would be 32 bits, which was way too much (they thought.) So they came up with a rather brilliant (blah) way to do their addressing- they would use two registers. They decided that they would not be 32bits, but the two registers would create 20 bit addressing. And thus Segments and OFFsets were born. And now the confusing specifics.


OFFSET = SEGMENT*16
SEGMENT = OFFSET /16 ;note that the lower 4 bits are lost


SEGMENT * 16 |0010010000010000----| range (0 to 65535) * 16
+
OFFSET |----0100100000100010| range (0 to 65535)
=
20 bit address |00101000100100100010| range 0 to 1048575 (1 MEG)

This shows how DS:SI is used to construct a 20 bit address.

Segment registers are: CS, DS, ES, SS. On the 386+ there are also FS & GS

Offset registers are: BX, DI, SI, BP, SP, IP. In 386+ protected mode, ANY general register (not a segment register) can be used as an Offset register. (Except IP, which you can't access.)

CS:IP => Points to the currently executing code.
SS:SP => Points to the current stack position.

If you'll notice, the value in the SEGMENT register is multiplied by 16 (or shifted left 4 bits) and then added to the OFFSET register. Together they create a 20 bit address. Also Note that there are MANY combinations of the SEGMENT and OFFSET registers that will produce the same address. The standard notation for a SEGment/OFFset pair is:

SEGMENT:OFFSET or A000:0000 ( which is, of course in HEX )

Where SEGMENT = 0A000h and OFFSET = 00000h. (This happens to be the
address of the upper left pixel on a 320x200x256 screen.)

You may be wondering what would happen if you were to have a segment value of 0FFFFh and an offset value of 0FFFFh.

Take notice: 0FFFFh * 16 (or 0FFFF0h ) + 0FFFFh = 1,114,095, which is
definately larger than 1 MEG (which is 1,048,576.)

This means that you can actually access MORE than 1 meg of memory! Well, to actually use that extra bit of memory, you would have to enable something called the A20 line, which just enables the 21st bit for addressing. This little extra bit of memory is usually called "HIGH MEMORY" and is used when you load something into high memory or say DOS = HIGH in your AUTOEXEC.BAT file. (HIMEM.SYS actually puts it up there..) You don't need to know that last bit, but hey, knowledge is good, right?

Now, I think it's over here and I'm exposing to you about the "REGISTERS" in the next post. See ya!

No comments: