Segmentation in 8086
Memory segmentation is an attempt to address more memory than the processor architecture would normally allow.
In the case of the 8086/8088, a 16 bit processor, you would normally expect addressibility of 64 kb, because that is what the instruction set is capable of developing as an effective address, either in the case of a direct address, an indirect address, or an indexed address, since all of its registers are 16 bits in size.
What Intel did was provide four more registers called segment registers which would provide the base address of an address in physical memory to which the processor generated effective address would be added. The segment register is still 16 bits in size, but it is left shifted by four before being added to the effective address. This creates a physical address that is 20 bits in size, for a total address range of 1 mb.
Note that you are still constrained to a segment size of 64 kb, in that you must stay within 64 kb unless you intend to change the value of one of the segment registers. This hampers the ability to access any arbitrary location in memory, effectively making it a two step operation – load the segment register – then access the offset address.
In the 8086/8088 there are four segment registers; Code Segment (CS), Data Segment (DS), Stack Segment (SS), and Extra Segment (ES). All opcode access is from CS. Default data access is from DS, unless a segment prefix is applied. All stack operations are from SS. Certain repeated string operations take place between DS and ES.
Because of the segmented architecture, the concept of near and far grew up with the original PC and DOS and Windows. Basically, a near address was a 16 bit address that assumed the current segment, while a far address was a 32 bit address that contained both a segment and an offset. Note that the concept of a flat 32 bit address did not come into full play until true 32 bit operating systems hit the street, and that did not occur until the introduction of the 80386.