On 8/30/12 7:47 AM, Malcolm McLean wrote:
> בתאריך יום חמישי, 30 באוגוסט 2012 02:09:02 UTC+1, מאת Les Cargill:
>> Keith Thompson wrote:
>>
>> The C89 flavors of MSC supported both "void*" and "near"/"far". TINY
>> MODEL FTW!
>>
> The idea of the "models" was that you could write program without the
> near/far non-standard extensions. Under "huge", if I remember rightly,
> all pointers were 32 bit and it did some inefficient magic to hide the
> segments and give you what looked like flat memory. Under "large",
> pointers were 32 bits but you couldn't allocate a block of more than
> 64 K.
> Under "tiny" all code and data had to fit within the same 64K segment,
> which led to the most efficient machine code. But you could use far
> pointers to allocate data in other segments. So you ended up rewriting
> fucntions like "farmemcpy", because the standard library only worked
> with the standard pointers.
>
>
>
>
The models came about due to the memory structure of the 16 bit x86
architecture. Addresses were in general greater than 16 bits in length,
while address registers were only 16 bits long, and were combined with a
"segment register" to convert the value to a full address. (depending on
what mode the processor was in would change how the conversion was done).
Near pointers only stored the value of the address register, and the
segment register was assumed by the type of pointer (the Data Segment
Register for "data" pointers, and the Program Segment Register for
function pointers). In addition, data pointers had a huge type, which
was like a far pointer, but could point to an object that might be
bigger than a single segment, and the compiler would need to do
additional work on address arithmetic to handle this. It mostly was used
in "Real" mode, where the Segment register was just added to the address
register after shifting up the Segment register 4 bits (giving a 20 bit
final memory address).
The program model determined what were the default sizes for each type
of pointer.
Model Data Code
Tiny near near
Small near near
Medium near far
Compact far near
Large far far
Huge huge far
The difference between Tiny and Small was that in Tiny, the code and
data were in the same segment, while in Small they were in distinct
segments.
It was by far more common to have near/far pointers in code that had a
default near size of pointers, to handle a limited number of
objects/functions that would be placed outside the default near block to
make room for them, sometimes to access things outside the current program.
Note also that the 32 bit x86 family of processors still have these
memory models (and 48 bit "far" pointers), they are just mostly ignored
and most programs are just done in the Tiny or Small model, after all
who should need more than 4GB of address space

The resurgence of
memory models for programs was headed off (for now at least) with the
introduction of 64 bit processors.