The MASM Forum Archive 2004 to 2012

Miscellaneous Forums => 16 bit DOS Programming => Topic started by: carlottagp on November 22, 2006, 04:17:15 PM

Title: Size of DATA segment
Post by: carlottagp on November 22, 2006, 04:17:15 PM
I am developing 16-bit programs to generate and work with prime numbers.  Now
that I'm getting to numbers larger than 65,535, I would like to define an array
which can hold more than 9,000 numbers, for example.  When I put the following
line into the DATA definitions, I get an error message:

Line:         prime         WORD        0A000h   DUP  (0)

Error message:   64K limit exceeded   -   DATA   (or words to that effect)

(even though A000 is nowhere near 32,000...)

Is there a way to tell the program that I need a larger DATA segment?

Thanks,

Mike O'Neill
Title: Re: Size of DATA segment
Post by: japheth on November 22, 2006, 04:34:07 PM

Hi,

> (even though A000 is nowhere near 32,000...)

A000h is indeed not near 32,000, but it is well above, not below. Are you new to programming...?

Title: Re: Size of DATA segment
Post by: carlottagp on November 22, 2006, 04:43:11 PM
It was a silly mistake; I was thinking about 64K (bytes), and dividing by two.  I suspect that
the 64K "limit" quoted to me in the assembler error message referred to bytes rather than
words.  Howwever, I still need to increase the size of the DATA segment, if that is
possible.  The program that I have now generates all the primes up to a one-word limit,
and then factorizes all the numbers up to that limit, printing out all the factors and
identifying the primes.  It's a beautiful program, but I'd like to extend its range...

Mike
Title: Re: Size of DATA segment
Post by: japheth on November 22, 2006, 07:25:57 PM

> Howwever, I still need to increase the size of the DATA segment, if that is possible.

Increasing size of _DATA beyond 64 kB may be difficult because most linkers will complain about DGROUP > 64 kB or similiar things. But you can define an extra segment for your array:


        .286
        .model small
        .386

largeseg segment para public 'data'
array label word
     db 8000h dup (0)
     db 8000h dup (0)
     db 8000h dup (0)
     db 8000h dup (0)
largeseg ends

       .code

       mov ax,seg array
       mov ds,ax
       mov si, offset array
        ...



You may have noticed that I defined the array in chunks of 8000h bytes. That is to workaround MASM bugs, which has problems with arrays larger 64 kB (at least in the non-flat memory models). It might be a good idea to not locate the array statically in the binary but alloc the memory dynamically at runtime.

The more serious problem is the 16-bit limitation of offsets in real-mode. That is, you cannot just let esi point to the array and then access any item by mov ax,[esi]. For this you will need to run your program in protected-mode.

Title: Re: Size of DATA segment
Post by: MichaelW on November 23, 2006, 02:20:55 AM
Mike,

Another alternative would be to handle your arrays similar to the way the Microsoft Basics handled huge dynamic arrays that could span multiple segments. Basically, for each array access, instead of using only an offset address, you use a segment address and an offset address. One conceptually simple and easy to implement method of doing this would be:

Start with an array index.

Convert the index to a byte offset.

Combine the byte offset with the segment address of the array to create a 20-bit absolute address.

Decompose the absolute address into a 16-bit segment address and a 4-bit offset address.

Load the segment address into a segment register (probably ES).

Load the offset address into a base or index register.

Access the array element through the base or index register, using a segment override as necessary.

I would implement this as two procedures, one to write array elements, and one to read array elements.

And for a simpler solution, code your program as a 32-bit Windows app :)

Title: Re: Size of DATA segment
Post by: carlottagp on November 23, 2006, 04:54:49 PM
Thank you so much for the suggestions; I will look into this further.  Thinking about my program
a little more, I have realized that I will not be limited by memory constraints for a while yet.
There are only about 2,000 primes less than 65,535, so I am really nowhere near the 8000h
limit on the array.  All my primes larger than this number will need two words to express them,
and the high-word array will clearly be a lot smaller than the low-word array, considering the
way the primes are distributed; so I shall go for 7000h for the low-word array, and 1000h for
the high-word array, as a tentative starting point.  I hope to get to 500,000 before running out of memory;
at that point I shall try Michael's approach.  Having started to learn 16-bit programming in May,
I'm still enjoying myself, but 32-bit programming seems too difficult to get into.

Thanks again for all the help.

Mike