[comp.lang.c] Microsoft C 6.0 Base Pointer

huangj@mist.cs.orst.edu (Jen Che Huang) (10/30/90)

Has anybody effectively use base pointers in MSC 6.0?  I was wondering if
there is an increase in your code speed or not?  

My real question is, since base pointers work off segments and the 
maximum size of a segment on a PC is 64K, what happens when I need more
than 64K of memory.  Can I increase the size of segment that it allocates
in increments of 64K (64, 128, 192, etc.)?

And when I free the memory, does the memory get free back to DOS (or in
my case OS/2) or does the program keep the memory until termination?

Thanks
Jim Huang

lbr@holos0.uucp (Len Reed) (10/31/90)

In article <21418@orstcs.CS.ORST.EDU> huangj@mist.cs.orst.edu (Jen Che Huang) writes:
>Has anybody effectively use base pointers in MSC 6.0?  I was wondering if
>there is an increase in your code speed or not?  

Well, I haven't measured any increase, though it certainly must be there since
the code executes fewer instructions.  It probably could matter for something
like hash list chains, say in an implementation of compress.  For many
applications far pointers will not be noticeably slower.
>
>My real question is, since base pointers work off segments and the 
>maximum size of a segment on a PC is 64K, what happens when I need more
>than 64K of memory.  Can I increase the size of segment that it allocates
>in increments of 64K (64, 128, 192, etc.)?

No segment can be bigger than 64K.  Based pointers allow you to set up
pointers within a segment.  You can have more than one segment, so that
they allow access to more memory than does the small model, but they
are faster than using far pointers.  You can have more than one base,
so that you can have a lot of memory.  But you'll need far pointers to
point from one segment to another.

With a near pointer, the compiler assumes that the
target is in the default data group and accesses the target thru the DS
register.

int x;
int near *p;
x = *p;

would generate something like

mov bx,p
mov ax,[bx]
mov x,ax

Change the "near" to "far" and you get something like

les bx,p
mov ax,es:[bx]
mov x,ax

The LES is much slower than the mov, since it has to access two words.
The segment prefix override costs time on an 8088 if you're using one.
The pointer p takes 4 bytes instead of 2.

Based (actually _based) pointers are in between.  In the above example
they'll be no better than far pointers.  Where they are useful is when
you have several pointers to the same segment.  In this case the compiler
doesn't have to keep reloading the ES register.

int x, y, z;
_segment myseg;
int _based(myseg) *p;
int _based(myseg) *q;
int _based(myseg) *r;

x = *p;
y = *q;
z = *z;

would be

mov es,myseg
mov bx,p
mov ax,es:[bx]
mov x,ax

mov bx,q
mov ax,es:[bx]
mov y,ax

mov bx,r
mov ax,es:[bx]
mov z,ax

With far pointers the compiler couldn't know that p, q, and r point
to the same segment and therefore it would have to reload the ES for
each of the three assignments.  The pointers themselves are also only
2 bytes long instead of the 4 they'd be with far pointers.

Where would one use such a contruction?  I've used them to access the
PSP.  Or how about a data structure that gets malloc'ed and contains
linked lists.  The links could be maintained using _based pointers,
which could be traversed faster than far pointers.

>And when I free the memory, does the memory get free back to DOS (or in
>my case OS/2) or does the program keep the memory until termination?

When you free what memory?  We've only talked about pointers, not what they
point to.  If you malloc memory, when you free it it may or may not got
back to the OS.  The malloc/free mechanism gets memory from the OS when it
needs it, but gets it in chunks.  If you malloc ten bytes, it may get 8K
and then dole memory out from that 8K when you call malloc over and over.
When you free memory, it won't go back to the OS unless you free everything
in a chunk.
-- 
Len Reed
Holos Software, Inc.
Voice: (404) 496-1358
UUCP: ...!gatech!holos0!lbr