[comp.lang.c] Large arrays in MSDOS

scott@hpcvca.CV.HP.COM (Scott Linn) (10/25/89)

Hello,

I've been having a problem trying to use an array greater than 64k on
an msdos machine.  What I have is the following:

char foo;
char FAR *bigbuf;
.
.
.
bigbug=farmalloc(125000L);

Then, I try to use bigbuf as a linear array:

bigbuf((long) some_pointer*some_num) = foo;

(I have compiled using the D model)

I am having problems with getting this to work, and I'm not sure if it's
something in my implementation, or my whole method is bogus.  Does
anyone out there know if this should work?

Thanks,

Scott Linn
hplabs!scott@hpcvcbh

readdm@walt.cc.utexas.edu (David M. Read) (10/26/89)

In article <4010005@hpcvca.CV.HP.COM> scott@hpcvca.CV.HP.COM  writes:
>
>Hello,
>
>I've been having a problem trying to use an array greater than 64k on
>an msdos machine.  What I have is the following:
>
Remember that the 80x86 processors use segmented architecture, so 64K is
a kind of barrier.  The way to get around the barrier is with use of the
'huge' keyword.  Read the manuals closely, for there are some limitations
on what you can do with it.


----------------------------------------------------------------------------
David M. Read                        best -=>  readdm@walt.cc.utexas.edu
                           all-else-fails -=>  read@physics.utexas.edu

"...[he's] stupid and he's ignorant but he's got guts...and guts is enough!"
----------------------------------------------------------------------------

scott@hpcvca.CV.HP.COM (Scott Linn) (10/26/89)

/ hpcvca:comp.lang.c / readdm@walt.cc.utexas.edu (David M. Read) / 10:36 am  Oct 25, 1989 /

>In article <4010005@hpcvca.CV.HP.COM> scott@hpcvca.CV.HP.COM  writes:
>>
>>Hello,
>>
>>I've been having a problem trying to use an array greater than 64k on
>>an msdos machine.  What I have is the following:
>>
>Remember that the 80x86 processors use segmented architecture, so 64K is
>a kind of barrier.  The way to get around the barrier is with use of the
>'huge' keyword.  Read the manuals closely, for there are some limitations
>on what you can do with it.

Yes, this was the problem.  I realize that the architecture is
segmented, but I was under the (mistaken!) impression that far
pointers would be able to address more than 64k.  The problem seems to
be that the pointer arithmetic only applies to the offset, and not the
segment.  Thus, wrapping occurs.  My compiler (Datalight) does not
have the Huge model, so I'm kind of hosed.  I will probably address
the array using two pointers, where the second pointer is composed by
the first one cast to a long, the correct offset added, then cast back
to a far pointer.  This should solve the arithmetic problem.

Thanks to all who replied in notes or mail.

Scott Linn
hplabs!scott@hpcvcbh

ben.pedersen@canremote.uucp (BEN PEDERSEN) (10/27/89)

Howdy Scott,

Your message said,

SM>I've been having a problem trying to use an array greater than 64k
SM>on an msdos machine.  What I have is the following:

SM>char foo;
SM>char FAR *bigbuf;
SM>.
SM>.
SM>.
SM>bigbug=farmalloc(125000L);

SM>Then, I try to use bigbuf as a linear array:

SM>bigbuf((long) some_pointer*some_num) = foo;

SM>(I have compiled using the D model)

SM>I am having problems with getting this to work, and I'm not sure if
SM>it's something in my implementation, or my whole method is bogus.
SM>Does anyone out there know if this should work?

I'm not sure which compiler you are using or what the 'D model'
represents but I put together the following using Zortech C under the
small memory model,

#include <stdio.h>
#include <dos.h>

main()
{
    char foo;
    char far *bigbuf;
    unsigned long some_num;

    foo = 'A';
    some_num = 85000L;

    printf("\n%lu bytes of memory available\n", farcoreleft());

    if((bigbuf = (char far*)farmalloc(125000L)) == NULL) {
        printf("\nfarmalloc failed!\n");
        exit(1);
    }

    printf("\nuninitialized: *(bigbuf + some_num) == \'%c\' \
            (ie. garbage)\n",*(bigbuf + some_num));

    *(bigbuf + some_num) = foo;  /* assign 'A' to a bigbuf location */

    printf("\n  initialized: *(bigbuf + some_num) == \'%c\' \
            (ie. the right stuff)\n",*(bigbuf + some_num));

    farfree(bigbuf);
}

It produced the following output on my system,

412032 bytes of memory available

uninitialized: *(bigbuf + some_num) == 'l' (ie. garbage)

  initialized: *(bigbuf + some_num) == 'A' (ie. the right stuff)

I am not quite sure about everything you seem to be attempting to do in
this statement,

SM>bigbuf((long) some_pointer*some_num) = foo;

Since you aren't using indirection to dereference the pointer 'bigbuf',
(ie. specify lvalue assignment) this would fail. The statement, as it
is, is attempting to tell the compiler to assign the address of 'foo' to
'bigbuf' (and something I cannot decipher).

'bigbuf' is a pointer and to use the address space it points to as a
linear array you must make use of pointer arithmetic. Locations within
that address space are relative to 'bigbuf'.

When assigning the pointer returned by farmalloc() to a pointer to far
character you should perform explicit type conversion on that returned
pointer because otherwise it is of type void (ie. unspecified type).

As my example attempts to point out, the contents of bigbuf's address
space are uninitialized garbage until it is explicitly initialized.

I hope this is the type of information you were looking for. If not let
me know if I can be more specific.

Ben Pedersen, Sysop
C-Power BBS
---
 * QDeLuxe 1.10 #2134  We're just tourists here making fools of ourselves

Bob.Stout@p6.f506.n106.z1.fidonet.org (Bob Stout) (10/27/89)

To use any single data object over 64K under most MS-DOS compilers requires  
the use of huge memory model. The problem is that the pointers to the array  
still consist of a segment and an offset with a range of 64K. To access arrays  
larger than 64K, the array pointer must be normalized for each access to avoid  
wrapping around at 64K. 

john@wsl.UUCP (John Allen on wsl) (10/28/89)

In article <4010005@hpcvca.CV.HP.COM> scott@hpcvca.CV.HP.COM (Scott Linn) writes:
>
>Hello,
>
>I've been having a problem trying to use an array greater than 64k on
>an msdos machine.  What I have is the following:
>
>char foo;
>char FAR *bigbuf;
>.
>.
>.
>bigbug=farmalloc(125000L);
>
>Then, I try to use bigbuf as a linear array:

Try changing you code to something like his:

char ch;
char HUGE *buf;

.
.
.
.
buf = farmalloc(125000L);

buf[some_num] = ch;

................
The HUGE keyword causes pointer arithmetic to become effectively linear.
i.e. Both the segment and offset are modified when subscripting and doing
pointer calculations.

NOTE:- HUGE pointer manipulation is not particularly fast on iApx86 hardware.



-- 

				   "Don't quote me on any issue whatsoever."