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?
-
4Use different segments, and change them as needed. Welcome to the 1980's! – Chris Stratton Nov 03 '14 at 19:55
-
4Brings back memories (pun intended) ;) – Majenko Nov 03 '14 at 20:05
-
By the way, it's not _external_ memory; that would be the 5¼", the Winchester etc. RAM is internal. Maybe you are confused with _extended_ memory. – Mr Lister Nov 04 '14 at 07:03
3 Answers
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.

- 55,955
- 9
- 105
- 187
Also note that since the 8086 had a 20-bit addressing scheme, those segment offsets overlapped every 16 bytes.
For instance if you had a CS at 0x0010 and a SS at 0x0011, [CS]:[0x0010] = [SS]:[0x0000]

- 41
- 1
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]

- 249
- 2
- 9
-
1Memory addresses which include a [BP] offset use the SS register rather than DS; indeed, I think segment prefixes are ignored with instructions using those addressing modes on the 8088, so they'll they always use SS even if another segment prefix is given. – supercat Nov 03 '14 at 23:11
-
1You're right about BP - the default segment register for it is SS. However DS remains the default for AX, BX, CX, DX and of course for SI which I forgot to mention. There's also DI, which is assigned to ES if I remember well (at least in movsb/movsw instructions). – emesik Nov 03 '14 at 23:21
-
2On the 8086, there are 24 addressing modes of the form base+disp+ofs, where base is nothing, BX, or BP; disp is nothing, SI, or DI, and ofs is 0, 1, or 2 bytes. Three three-way choices would allow 27 possibilities, but the [nothing+nothing+ofs] mode requires a 2-byte offset, and [BP+nothing+ofs] requires a 1- or 2-byte offset. The STOSB, STOSW, MOVSB, and MOBSW instructions store to ES:DI; those are the only instructions that use ES by default (and they cannot use any other segment). – supercat Nov 03 '14 at 23:30
-
It's not some assembler notation that `ds` is default — it's how instruction set works. Namely, if you override segment, the assembler will generate the corresponding segment override prefix, otherwise it generates instruction without prefix, and this effectively makes `ds` default (for instructions which do obey this principle). – Ruslan Nov 04 '14 at 08:54
-
Also, your use of `ax` is flawed. There's no such mode of addressing like `[ax]`. You can either use `[eax]` starting with i386, or are limited to `[bx+si]`, `[bx+di]`, `[bp+si]`, `[bp+di]`, `[si]`, `[di]`, `[bp]`, `[bx]`. – Ruslan Nov 04 '14 at 08:58