3

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?

saurabh
  • 55
  • 4

3 Answers3

11

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.

Majenko
  • 55,955
  • 9
  • 105
  • 187
4

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]

see: http://en.wikipedia.org/wiki/Intel_8086#Segmentation

pm_752566
  • 41
  • 1
2

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]
emesik
  • 249
  • 2
  • 9
  • 1
    Memory 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
  • 1
    You'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
  • 2
    On 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