# 8086 Memory segment falling on 16-byte boundaries

I was reading in 8086 datasheet and I found this phrase that I couldn't understand in memory organisation :

memory is logically divided into code, data, extra data, and stack segments of up to 64K bytes each, with each segment falling on 16-byte boundaries.

I know what segmants mean but what they mean by "... segment falling on 16-byte boundaries...

-
I'm sure this belongs on StackOverflow. –  sharptooth Mar 16 '12 at 14:29
this question is related to hardware not to software any way thank you for attention my ! –  yahya tawil Mar 16 '12 at 14:31
@sharptooth It's computer architecture, and I think it can fit here also –  clabacchio Mar 16 '12 at 14:32

This means that each segment starts at an address that is a multiple of 16. This is achieved as follows.

Addresses in 8086 are 20 bit long. Addresses are computed from a segment start and an offset, both are 16 bit. The 16-bit segment start is shifted left by 4, then the offset is added. These two operations are performed in a 20-bit register, so the result is a 20-bit address.

Since the segment start is shifted left by 4 the result of this shift has its lower 4 bits set to zero at all times and so is a multiple of 16. There's no way for a segment to start at an address that is not a multiple of 16 because of this.

-

Although many programmers grumbled about the 8086 segmented architecture when it came out, and although a few things could have been done to improve it (but weren't), it's nonetheless better at providing a meg of fungible memory address space than any other 16-bit architecture I know of.

Each logical address consists of two parts: a 16-bit segment and a 16-bit offset. Physical addresses are generated by adding the segment register, shifted left four bits, to the offset register (not shifted) and outputting the 20-bit result. Thus, segment 0000 [all numbers in hex] offsets 0000 to FFFF represent physical addresses 00000 to 0FFFF. Adding those offsets to various other segments will yield other address ranges:

Seg. Phys. Range
0000 00000-0FFFF
0001 00010-1000F
0002 00020-1001F
0FFF 0FFF0-1FFEF
1000 10000-1FFFF
FFFF FFFF0-0FFEF (or 10FFEF if higher physical addressing bits exist)


One useful effect of this is that if memory can be divided into logical chunks of 64K or less each, aligned on 16-byte boundaries, one can determine for each chunk (at the time of allocation, which could be when code is linked, when it's loaded, or while it's executing) the segment value where the chuck should. One can then access memory within any chunk by simply loading that pre-determined segment value and then using offsets directly, without having to do any actual computation on segment registers. Because the segment register is multiplied by 16 when computing a physical address, chunks have to be aligned on 16-byte boundaries. In exchange for that minor inconvenience, however, one gains the ability to have memory chunks cross 64K boundaries without restriction or hassle.

-
thank you every one for answering me because all your answer give me the first step to understand segmentation of memory in 8086. I found useful article about segmentation in 8086 like these one: thestarman.pcministry.com/asm/debug/Segments.html homepage.smc.edu/morgan_david/cs40/segmentation.htm homepage.smc.edu/morgan_david/cs40/segmentation.htm the question is know is there any new technologies in segmentation memories better than " segment:offset" –  yahya tawil Mar 16 '12 at 17:44
@yahyatawil - oh there are definitely improvements. Even the 80286 offered improved segmentation. –  JustJeff Mar 17 '12 at 23:02
"One can then access memory ... without having to do any actual computation on segment registers." -- to put an even finer point on this: this scheme allowed for position independent code to be written very easily. You didn't have to worry, while coding, about where in memory the code would be put. The OS could then put the binary wherever was convenient, set the segment regs accordingly, and away you go. –  JustJeff Mar 17 '12 at 23:37
@JustJeff: The 80286 made segments refer to logical rather than physical addresses. Actually, what I'd like to see would be a system which would use 32-bit segment designators and 32-bit offsets. No application is going to need 16 quintillion bytes worth of stuff; if an application would need more than four billion distinct objects, that would be a sign individual objects should be bigger. If any object would need to be over four billion bytes, that should be a sign that individual objects should be smaller. –  supercat Mar 18 '12 at 22:09
heheh - the 64K limit replaced with a 4G limit. –  JustJeff Mar 19 '12 at 2:34

Doing the math, 216=64k, which means that a 64k segment can be addressed by a 16-bit value.

So if you have a set of 64k stack segments, you can select the single segment with a segment-address value and then the offset in the segment is a 16-bit address.

Note that they can be up to 64k, but also smaller: in that case, the address must still be of 16 bit to preserve the alignment. AND, again to have the alignment, each segment must start at the bottom of a 64k block.

-
well .. 8086 segmentation offers no memory protection, and segments could start on any 16 byte boundary - there was no restriction to 64K boundaries at all; and a given physical address can have many segment:offset representations. For example, in PC-DOS, there were a number of DOS variables stored at the 1K mark, which could be called 0:0400, but was often referred to as 40:0. Also, there were four segments: code, data, stack and extra, and there was no restriction about these overlapping or not. –  JustJeff Mar 17 '12 at 23:05
Also, there was no way to enforce a segment smaller than 64K in the 8086, because there were no segment limit registers. Offsets 0x0000 to 0xFFFF would always function in any segment. –  JustJeff Mar 17 '12 at 23:10