INF: Huge Indirection May Not Cross Segment Boundaries

ID Number: Q50733

5.10 6.00 6.00a 6.00ax 7.00 | 5.10 6.00 6.00a

MS-DOS | OS/2

Summary:

Microsoft C will never generate an array element that spans a segment

boundary. If a customer generates a scenario where this situation

occurs, Microsoft C will generate incorrect addresses for the element

that crosses the segment boundary. Placing elements such that they

could cross a segment boundary is an incorrect coding technique, not a

problem with Microsoft C and huge pointer addressing.

More Information:

For instance, if a huge character buffer has been allocated and

structure data has been copied to this buffer, it is possible to

access this data in structure format. First set a huge pointer to the

address of the structure you want, and then specify the huge pointer

followed by the structure pointer operator (->) and the name of

element you want to access.

However, if the structure you are looking at crosses a segment

boundary, then the indirection will fail. If the element of the

structure you are referencing is in another segment, your pointer will

usually end up offsetting by the correct number of bytes, but in the

current segment and not the next segment.

Sample Code

-----------

char huge buffer[70000]; /* Any huge buffer larger than 64K */

struct x { int x,y,z; }; /* Any structure */

/* Assume that buffer has been filled with many structures of type x.

Because the structures were put into the buffer via byte copy, it

is very likely that one of the structures will cross over the segment

boundary. */

struct x huge *test_ptr; /* A huge pointer to x */

test_ptr = (struct x huge *)(buffer+( 65536 - sizeof(struct x) ) );

/* test_ptr is now equal to some offset into huge character buffer.

It is assumed that the user has given test_ptr a legitimate address

of a structure that is contained in the buffer in an attempt to access

that structure. */

test_ptr->z = 5;

/* The line above will create an incorrect address for the element z if

z is in a segment other than the one specified by the huge pointer.

This address will probably end up as the correct offset but in the

same segment because, although the pointer is huge, it still will not

compute the segment when used with indirection. This is also why

huge structure arrays are padded and why huge arrays larger than

128K must have elements whose size is a power of two. */

Note: This problem can avoided by simply creating a huge array of

structures instead of characters. The compiler will take care of

padding the array so that an array element (a structure) will not

cross a segment boundary.

This apparently is a problem in the compiler because the huge pointer

cannot access data beyond a segment boundary. The situation where an

array element crosses a segment boundary would never be generated by

Microsoft C, however. Accordingly, the huge pointer arithmetic does

not account for such a situation. This is not a problem in the

compiler, but an error in the code.

Additional reference words: 5.10 6.00 6.00a 6.00ax 7.00