Take a look at the following output from "debug.exe":
[snip]
My bet is that MS-DOS is not running in protected mode. "selectors" only
exist in protected mode. The context of this thread is 16-bit or 32-bit
protected mode, where loading an invalid selector into a segment register
will cause a trap.
Ok explain how memory is access in MS-DOS at an address greater than
0xFFFF since it is running in 16-Bit real mode 0xFFFF is the highest
memory address you can possibly have.
Incorrect. You can address 1 megabyte in real mode. (using "far"
pointers, which in some memory models are the default for C). Ever
wonder why the addresses for the BIOS and hardware devices start
at 1 megabyte and reach down to 640k?
But yet it was possible to use
the whole < 640Kb (subtract tsr's of course) region using far pointers and
memory selectors.
NO, you're not using memory selectors. You're using the segment
register to refer to the base of a segment in terms of multiples
of 16-byte "pages". Selectors exist only in protected mode.
In real mode, physical address = 16*segment register + offset .
The segment register and offset are each 16 bits in 16-bit real
mode. Thus, you can address 1 megabyte. Well, ok, in some cases
1 megabyte plus almost 64k. But what you put in a segment register
in real mode is *NOT* a selector.
In real mode, 0x0000:0x0080 and 0x0008:0x0000 refer to the same
byte. In 16-bit protected mode, these addresses may be nowhere
near each other, as each refers to a different potentially 64k-long
segment.
Some extended memory managers use protected mode but run MS-DOS in
virtual 8086 mode, where segment registers act like they are in
real mode, but "windows" in memory (typically in the 640k - 1024k
range) can be remapped to memory above 1 meg ("extended memory").
Others use some kind of hardware remapping not provided by the CPU
("expanded memory"). It is also possible to escape from 16-bit
real mode into 32-bit mode using instruction prefixes on Intel
[3456]86 processors.
In protected mode, there are 2**13 (8192) possible local table
entries and 2**13-1 (8191) possible global table entries (table
entry 0 is not used in the global table). Without changing the
table, you can address, in 16-bit protected mode, 8192*2**16 = about
0.5 gigabytes local memory, and almost the same in global memory,
using a 32-bit "far" pointer (16-bit selector, 16-bit offset). In
32-bit protected mode (16-bit selector, 32-bit offset), that's about
32 gigabytes each, local and global, for a 48-bit "far" pointer.
(The processor may not be able to address that much *PHYSICAL*
memory, though).
Gordon L. Burditt