News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Size of DATA segment

Started by carlottagp, November 22, 2006, 04:17:15 PM

Previous topic - Next topic

carlottagp

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

japheth


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...?


carlottagp

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

japheth


> 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.


MichaelW

#4
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 :)

eschew obfuscation

carlottagp

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