• 검색 결과가 없습니다.

details numerical constants and the RADIX directive

문서에서 Paradigm Assembler User's Guide (페이지 148-155)

Allocating data

Chapter 5 details numerical constants and the RADIX directive

Creating an instance of a structure or union

To create an instance of a structure or a union data type, use the structure or union name as a data allocation directive. For example, assume you've defined the following:

ASTRUC STRUC B DB "xyz"

C DW 1 D DD 2 ASTRUC ENDS BUNION UNION X DW ?

Y DD ? Z DB ? BUNION ends

Then the statements

ATEST ASTRUC ? BTEST BUNION ?

would create instances of the structure astruc (defining the variable atest) and the union bunion (defining the variable btest). Since the example contained the ? uninitialized data value, no initial data will be emitted to the current segment.

Initializing union or structure instances

Initialized structure instances are more complex than uninitialized instances. When you define a structure, you have to specify an initial default value for each of the structure members. (You can use the ? keyword as the initial value, which indicates that no specific initial value should be saved.) When you create an instance of the structure, you can create it using the default values or overriding values. The simplest initialized instance of a structure contains just the initial data specified in the definition. For example,

ASTRUC {}

is equivalent to

DB "xyz"

DW 1 DD 2

The braces ({}) represent a null initializer value for the structure. The initializer value determines what members (if any) have initial values that should be overridden, and by what new values, as you allocate data for the structure instance. The syntax of the brace initializer follows:

[member_name = value [,member_name = value... ]]

member_name is the name of a member of the structure or union. value is the value that you want the member to have in this instance. Specify a null value to tell Paradigm Assembler to use the initial value of the member from the structure or union definition.

A ? value indicates that the member should be uninitialized. Paradigm Assembler sets any member that doesn't appear in the initializer to the initial value of the member from the structure or union definition. For example,

ASTRUC {C=2,D=?}

is equivalent to

DB "xyz"

DW 2 DD ?

You can use the brace initializer to specify the value of any structure or union member, even in a nested structure or union.

Unions differ from structures because elements in a union overlap one another. Be careful when you initialize a union instance since if several union members overlap, Paradigm Assembler only lets one of those members have an initialized value in an instance. For example,

BUNION {}

is valid because all three members of the union are uninitialized in the union definition.

This statement is equivalent to

DB 4 DUP (?)

In this example, four bytes are reserved because the size of the union is the size of its largest member (in this case a DWORD). If the initialized member of the union is not the largest member of the union, Paradigm Assembler makes up the difference by reserving space but not emitting data. For example,

BUNION {z=1}

is equivalent to

DB 1

DB 3 DUP (?)

Finally, multiple initialized members in a union produce an error. For example, this is illegal:

BUNION {X=1,Z=2}

Note that if two or more fields of the union have initial values in the union definition, then using the simple brace initializer will also produce an error. The initializer must set all but one value to ? for a legal instance to be generated.

An alternative method of initializing structure and union instances is to use the bracket (< >) initializer. The values in the initializer are unnamed but are laid out in the same

order as the corresponding members in the structure or union definition. Use this syntax for the bracket initializer:

< [value [,value... ]] >

value represents the desired value of the corresponding member in the structure or union definition. A blank value indicates that you'll use the initial value of the member from the structure or union definition. A ? keyword indicates that the member should be uninitialized. For example, expression represents the desired value of the corresponding field in the record definition. A blank value indicates that you'll use the initial value of the field from the record definition. A ? keyword indicates that the field should be zero.

For example,

ASTRUC <"abc",,?>

is equivalent to

DB 'abc' DW 1 DD ?

If you specify fewer values than there are members, Paradigm Assembler finishes the instance by using the initial values from the structure or union definition for the remaining members.

ASTRUC <"abc"> ;Same as ASTRUC <"abc",,>

When you use the bracket initializer, give special consideration to nested structures and unions. The bracket initializer expects an additional matching pair of angle brackets for every level of nesting, so that Paradigm Assembler will treat the nested structure or union initializer as a single entity (to match the value in the instance). Alternatively, you can skip an entire level of nesting by leaving the corresponding entry blank (for the default value of the nested structure or union), or by specifying the ? keyword (for an uninitialized nested structure or union). For example, examine the following nested structure and union:

CUNION STRUC CTYPE DB ?

UNION ;Start Of union ;If CTYPE = 0, use this...

STRUC

CT0PAR1 DW 1 CT0PAR2 DB 2 ENDS

;If CTYPE=1, use this...

STRUC

CT1PAR1 DB 3 CT1PAR2 DD 4 ENDS

ENDS ;End of union

ENDS ;End of structure data type

The bracket initializer for this complex structure/union has two levels of nesting. This nesting must appear as matched angle brackets within the initializer, like

CUNION <0,<<2,>,?>>

This directive is equivalent to

DB 0 DW 2 DB 2

DB 2 DUP (?)

Creating an instance of a record

To create an instance of a record data type, use the name of the record data type as a data allocation directive. For example, assume you've defined the following:

MYREC RECORD VAL:3=4,MODE:2,SZE:4=15

Then, the statement

MTEST MYREC ?

would create an instance of the record myrec (defining the variable mtest). No initial data is emitted to the current segment in this example because the ? uninitialized data value was specified.

Record instances are always either a byte, a word, or a doubleword, depending on the number of bits Allocated in the record definition.

Initializing record instances

You must specify an initial value for some or all of the record fields when you define a record. (Paradigm Assembler assumes that any unspecified initial values are 0.) The simplest initialized instance of a record contains just the initial field data specified in the definition. For example,

MYREC {}

is equivalent to

DW (4 SHL 6) + (0 SHL 4) + (15 SHL 0)

;SHL is the shift left operator for expressions

The braces ({}) represent a null initializer value for the record. The initializer value determines what initial values should be overridden, and by what new values (as you allocate data for the record instance).

Use this syntax of the brace initializer for records:

{[field_name = expression [,field_name = expression... ]] }

field_name is the name of a field in the record. expression is the value that you want the field to have in this instance. A blank value indicates that you'll use the initial value of the field from the record definition. A ? value is equivalent to zero. Paradigm

Assembler sets any field that doesn't appear in the initializer to the initial value of the field from the record definition. For example,

MYREC {VAL=2,SZE=?}

is equivalent to

DW (2 SHL 6) + (0 SHL 4) +(0 SHL 0)

An alternative method of initializing record instances is to use the bracket (< >)

initializer. In this case, brackets delineate the initializer. The values in the initializer are unnamed but are laid out in the same order as the corresponding fields in the record definition. The syntax of the bracket initializer follows:

< [expression [,expression ... ]] >

expression represents the desired value of the corresponding field in the record definition. A blank value indicates that you'll use the initial value of the field from the record definition. A ? keyword indicates that the field should be zero. For example,

MYREC <,2,?>

is equivalent to

DW (4 SHL 6) + (2 SHL 4) + (0 SHL 0)

If you specify fewer values than there are fields, Paradigm Assembler finishes the instance by using the initial values from the record definition for the remaining fields.

MYREC <1> ;same as MYREC <1,,>

Creating an instance of an enumerated data type

You can create an instance of an enumerated data type by using the name of the enumerated data type as a data allocation directive. For example, assume you have defined the following:

ETYPE ENUM FEE,FIE,FOO,FUM

Then the statement

ETEST ETYPE ?

would create an instance of the enumerated data type etype (defining the variable etest).

In this example, no initial data is emitted to the current segment because the uninitialized data value is specified.

Enumerated data type instances are always either a byte, a word, or a doubleword, depending on the maximum value present in the enumerated data type definition.

Initializing enumerated data type instances

You can use any expression that evaluates to a number that will fit within the enumerated data type instance; for example,

ETYPE ? ;uninitialized instance

ETYPE Foo ;initialized instance, value Foo

ETYPE 255 ;a number outside the ENUM that also fits

Creating an instance of a table

To create an instance of a table data type, use the table name as a data allocation directive. For example, assume you have defined the following table:

TTYPE TABLE VIRTUAL DoneProc:WORD=DoneRtn, \ VIRTUAL MsgProc:DWORD-MsgRtn, \ VIRTUAL DoneProc:WORD-DoneRtn

Then, the statement

TTEST TTYPE ?

would create an instance of the table ttype (defining the variable ttest). No initial data will be emitted to the current segment in this example because the ? uninitialized data value was specified.

Initializing table instances

When you define a table, you must specify an initial value for all table members. The simplest initialized instance of a table contains just the initial data specified in the definition. For example,

TTYPE {}

is equivalent to

DW MoveRtn DD MsgRtn DW DoneRtn

The braces ({}) represent a null initializer value for the structure. The initializer value determines what members (if any) have initial values that should be overridden, and by what new values, as you allocate data for the table instance. Here's the syntax of the brace initializer:

{ [member_name = value [,member_name = value...]] }

member_name is the name of a member of the table. value is the value that you want the member to have in this instance. A blank value indicates that you'll use the initial value of the member from the table definition. A ? value indicates that the member should be uninitialized. Paradigm Assembler sets any member that doesn't appear in the initializer to the initial value of the member from the table definition. For example,

TTYPE (MoveProc=MoveRtn2,DoneProc=?)

is equivalent to

DW MoveRtn2 DD MsgRtn DW ?

Creating and initializing a named-type instance

You can create an instance of a named type by using the type name as a data allocation directive. For example, if you define the following type:

NTTYPE TYPEDEF PTR BYTE

the statement

NTTEST NTTYPE ?

creates an instance of the named type nttype (defining the variable nttest). No initial data is emitted to the current segment in this example because you specified the ? uninitialized data value.

The way that you initialize a named-type instance depends on the type that the named type represents. For example, NTTYPE in the previous example is a word, so it will be initialized as if you had used the DW directive, as follows:

NTTYPE 1,2,3 ;Represents pointer values 1,2,3.

DW 1,2,3 ;Same as NTTYPE 1,2,3.

However, if the named type represents a structure or table, it must be initialized the same way as structures and tables are. For example,

foo STRUC f1 DB ? ENDS

bar TYPEDEP foo

bar (f1=1) ;Must use structure initializer.

Creating an instance of an object

Creating an instance of an object in an initialized or uninitialized data segment is exactly the same as creating an instance of a structure. In fact, objects in Paradigm Assembler are structures, with some extensions. One of these extensions is the

@Mptr_<object_name> structure member.

An object data type with virtual methods is a structure having one member that points to a table of virtual method pointers. The name of this member is

@Mptr_<object_name>. Usually, you would initialize an instance of an object using a constructor method. However, you could have objects designed to be static and have no constructor, but are instead initialized with an initlilizer in a data segment.

If you use the @Mptr_<object_name> member's default value, Paradigm Assembler win correctly initialize the object instance.

Another difference between structures and objects is that objects can inherit members from previous object definitions. When this inheritance occurs, Paradigm Assembler handles it as a nested structure. Because of this, we do not recommend using bracket (< >) initializers for object data.

Creating an instance of an object's virtual method table

Every object that has virtual methods requir6s an instance of a table of virtual methods to be available somewhere. A number of factors determine the proper placement of this table, including what program model you're using, whether you want near or far tables, and so forth. Paradigm Assembler requires you to place this table. You can create an instance for the most recently defined object by using the TBLINST pseudo-op, with this syntax:

TBLINST

TBLINST defines @TableAddr_<object_name> as the address of the virtual table for the object. It is equivalent to

@TableAddr_<object_name> @Table_<object_name> {}

C h a p t e r

13

문서에서 Paradigm Assembler User's Guide (페이지 148-155)