4.35 Pointers to Records


4.35 Pointers to Records

During execution, your program may refer to structure objects directly or indirectly using a pointer. When you use a pointer to access fields of a structure, you must load one of the 80x86's 32-bit registers with the address of the desired record. Suppose you have the following variable declarations (assuming the Object8 structure from an earlier section):

 static      Cube:           Object8;      CubePtr:      pointer to Object8 := &Cube; 

CubePtr contains the address of (i.e., it is a pointer to) the Cube object. To access the Color field of the Cube object, you could use an instruction like "mov( Cube.Color, eax );". When accessing a field via a pointer you need to load the address of the object into a 32-bit register such as EBX. The instruction "mov( CubePtr EBX );" will do the trick. After doing so, you can access fields of the Cube object using the "[EBX+offset]" addressing mode. The only problem is "How do you specify which field to access?" Consider briefly, the following incorrect code:

      mov( CubePtr, ebx );      mov( [ebx].Color, eax );      // This does not work! 

There is one major problem with the code above. Because field names are local to a structure and it's possible to reuse a field name in two or more structures, how does HLA determine which offset Color represents? When accessing structure members directly (e.g., "mov( Cube.Color, EAX );") there is no ambiguity because Cube has a specific type that the assembler can check. "[EBX]", on the other hand, can point at anything. In particular, it can point at any structure that contains a Color field. So the assembler cannot, on its own, decide which offset to use for the Color symbol.

HLA resolves this ambiguity by requiring that you explicitly supply a type. To do this, you must coerce "[EBX]" to type Cube. Once you do this, you can use the normal dot operator notation to access the Color field:

      mov( CubePtr, ebx );      mov( (type Cube [ebx]).Color, eax ); 

By specifying the record name, HLA knows which offset value to use for the Color symbol.

If you have a pointer to a record and one of that record's fields is an array, the easiest way to access elements of that field is by using the base plus indexed addressing mode. To do so, you just load the pointer's value into one register and compute the index into the array in a second register. Then you combine these two registers in the address expression. In the example above, the Pts field is an array of eight point objects. To access field x of the i th element of the Cube.Pts field, you'd use code like the following:

      mov( CubePtr, ebx );      intmul( @size( point ), i, esi );   // Compute index into point array.      mov( (type Object8 [ebx]).Pts.x[ esi*4 ], eax ); 

If you use a pointer to a particular record type frequently in your program, typing a coercion operator, like "(type Object8 [ebx])" can get old pretty quick. One way to reduce the typing needed to coerce EBX is to use a text constant. For example, consider the following statement in a program:

 const      O8ptr: text := "(type Object8 [ebx])"; 

With this statement at the beginning of your program you can use o8ptr in place of the type coercion operator and HLA will automatically substitute the appropriate text. With a text constant like the above, the former example becomes a little more readable and writable:

      mov( CubePtr, ebx );      intmul( @size( point ), i, esi ); // Compute index into point array.      mov( O8Ptr.Pts.x[ esi*4 ], eax ); 




The Art of Assembly Language
The Art of Assembly Language
ISBN: 1593272073
EAN: 2147483647
Year: 2005
Pages: 246
Authors: Randall Hyde

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net