Question: If the external memory (1 MB) in 8086 based system is segmented into code, data, stack and extra which are all 64 kB, what do we do with the rest of the memory? Does it go waste?

Answer: 
In the 8086 each segment is, yes, 64KiB. Those segments can move though.

You set a "segment pointer" which defines where a segment starts. It acts as an address offset, which is added to the internal 16-bit address of the program counter (or other indexing register).

Changing the segment pointers is a trivial matter, so although you can only access 64KiB at a time, you can move that 64KiB window around at will to access the whole 1MiB of memory space.
Number of segment determines the place in the memory. Segment 0 starts at the physical 0 address of the memory. Segment 1 starts 0x10 bytes from the beginning, segment 2 at 0x20, etc.

Yes, segments start each 0x10 bytes but are 64k long, which means they overlap a lot.

There are segment registers: CS (code segment), DS (data segment), SS (stack segment) and ES (extra segment). Byte-grained addresses are obtained with pointer regiters: IP (instruction pointer), SP (stack pointer) and BP (base pointer).

The currently executed instruction is located at CS:IP (segment number from CS + IP bytes offset).

If you operate on data without explicitly specifying the segment, DS is the default (at least in Turbo Assembler notation). For example:

```
mov cx, [bp]

```

is the same as:

```
mov cx, ds:[bp]

```

I'm not sure about the exact syntax (it was some 15 years ago since I used it).

You cannot assign a value to a segment register directly. You have to do it through general registers, e.g.:

```
mov ax, 100h
mov ds, ax

```

So, to load a word from physical address 0x105 into BX, you may do it this way:

```
xor ax, ax  ; equal to mov ax, 0 but faster
mov ds, ax
mov ax, 105h
mov bx, [ax]

```

or, by using different segment:

```
mov ax, 10h
mov ds, ax
mov ax, 5
mov bx, [ax]

```