• Keine Ergebnisse gefunden

Procedure definition syntax

Im Dokument . TUrbo Assembler" (Seite 136-142)

Unless you specify version T31 0 or earlier, the Ideal mode syntax is no longer allowed in MASM mode.

You can use the PROC directive to declare procedures. Here's its Ideal mode syntax:

PROC name [[language modifier] language] [distance]

[ARG argument_list] [RETURNS item_list]

[LOCAL argument_list]

[USES item_list]

ENDP [name]

Use the following syntax in MASM mode:

name PROC [[language modifier] language] [distance]

[ARG argument_listl [RETURNS item_listl [LOCAL argument_list]

[USES item_listl [namel ENDP

Turbo Assembler also accepts MASM syntax for defining procedures. For more information on MASM syntax, see Chapter 3.

If you're using Turbo Assembler version T310 or earlier, use the following Ideal mode syntax:

Declaring NEAR or FAR

procedures

You can specify this as an argument to the MODEL statement.

See Chapter 7 for more information.

PROC [[language modifier] language] name [distance]

[ARG argument_list] [RETURNS item_list]

[LOCAL argument_list]

[USES item_list]

ENDP

Note that the only difference between the older versions of Turbo

Assembler and the later versions is that language and language_modifier have been moved to follow the procedure name to facilitate consistent function prototyping.

NEAR procedures are called with a near call, and contain a near return; you must call them only from within the same segment in which they're defined. A near call pushes the return address onto the stack, and sets the instruction pointer (IP) to the offset of the procedure. Since the code

segment (CS) is not changed, the procedure must be in the same segment as the caller. When the processor encounters a near return, it pops the return address from the stack and sets IP to it; again, the code segment is not changed.

FAR procedures are called with a far call and contain far returns. You can call FAR procedures from outside the segment in which they're defined. A far call pushes the return address onto the stack as a segment and offset, and then sets CS:IP to the address of the procedure. When the processor encounters a far return, it pops the segment and offset of the return address from the stack and sets CS:IP to it.

The currently selected model determines the default distance of a procedure. For tiny, small, and compact models, the default procedure distance is NEAR. For all other models, FAR is the default. If you don't use the simplified segmentation directives, the default procedure distance is always NEAR.

You can override the default distance of a procedure by specifying the desired distance in the procedure definition. To do this, use the NEAR or FAR keywords. These keywords override the default procedure distance, but only for the current procedure. For example,

MODEL TINY ;default distance near

;testl is a far procedure testl PROC FAR

;body of procedure

RET ;this will be a far return ENDP

;test2 is by default a near procedure test2 PROC

;body of procedure

RET ;this will be a near return ENDP

The same REt mnemonic is used in both NEAR and FAR procedures; Turbo Assembler uses the distance of the procedure to determine whether a near or far return is required. Similarly, Turbo Assembler uses the procedure distance to determine whether a near or far call is required to reference the procedure:

CALL testl ;this is a far call CALL test2 ;this is a near call

When you make a call to a forward referenced procedure, Turbo Assembler might have to make multiple passes to determine the distance of the procedure. For example,

testl PROC NEAR MOVax,lO CALL test2 RET testl ENDP test2 PROC FAR

ADD ax,ax RET test2 ENDP

When Turbo Assembler reaches the "call test2" instruction during the first pass, it has not yet encountered test2, and therefore doesn't know the distance. It assumes a distance of NEAR, and presumes it can use a near call.

When it discovers that test2 is in fact a FAR procedure, Turbo Assembler determines that it needs a second pass to correctly generate the call. If you enable multiple passes (with the 1m command-line switch), a second pass will be made. If you don't enable multiple passes, Turbo Assembler will report a "forward reference needs override" error.

You can specify the distance of forward referenced procedures as NEAR PTR or FAR PTR in the call to avoid this situation (and to reduce the number of passes).

Declaring a procedure language

testl PROC NEAR MOVax,lO

CALL FAR PTR test2 RET

testl ENDP

The previous example tells Turbo Assembler to use a far call, so that multiple assembler passes aren't necessary.

You can easily define procedures that use high-level language interfacing conventions in Turbo Assembler. Interfacing conventions are supported for the NOLANGUAGE (Assembler), BASIC, FORTRAN, PROLOG, C, CPP (C++), SYSCALL, STDCALL, and PASCAL languages.

Turbo Assembler does all the work of generating the correct prolog (procedure entry) and epilog (procedure exit) code necessary to adhere to the specified language convention.

You can specify a default language as a parameter of the MODEL directive.

See Chapter 7 for further details. If a default language is present, all procedures that don't otherwise specify a language use the conventions of the default language.

To override the default language for an individual procedure, include the language name in the procedure definition. You can specify a procedure language by including a language identifier keyword in its declaration. For example, a definition in MASM mode for a PASCAL procedure would be

pascalproc PROC PASCAL FAR iprocedure body pascalproc ENDP

Turbo Assembler uses the language of the procedure to determine what prolog and epilog code is automatically included in the procedure's body.

The prolog code sets up the stack frame for passed arguments and local variables in the procedure; the epilog code restores the stack frame before returning from the procedure.

Turbo Assembler automatically inserts prolog code into the procedure before the first instruction of the procedure, or before the first "label:" tag.

Prolog code does the following:

• Saves the current BP on the stack.

II Sets BP to the current stack pointer.

II Adjusts the stack pointer to allocate local variables.

II Saves the registers specified by USES on the stack.

Turbo Assembler automatically inserts epilog code into the procedure at each RET instruction in the procedure (if there are multiple RETs, the epilog code will be inserted multiple times). Turbo Assembler also inserts epilog code before any object-oriented method jump (see Chapter 4).

Epilog code reverses the effects of prolog code in the following ways:

EI Pops the registers specified by USES off the stack.

IS Adjusts the stack pointer to discard local arguments.

13 Pops the stored BP off the stack.

CI Adjusts the stack to discard passed arguments (if the language requires it) and returns.

The last part of the epilog code, discarding passed arguments, is performed only for those languages requiring the procedure to discard arguments (for example, BASIC, FORTRAN, PASCAL). The convention for other

languages (C, C++, PROLOG) is to leave the arguments on the stack and let the caller discard them. SYSCALL behaves like C++. For the STDCALL language specification, C++ calling conventions are used if the procedure has variable arguments. Otherwise, PASCAL calling conventions are used.

. . Turbo Assembler always implements the prolog and epilog code using the most efficient instructions for the language and the current processor selected.

Figure 10.1 How language affects procedures

See Chapter 13 for further information.

Turbo Assembler doesn't generate prolog or epilog code for

NOLANGUAGE procedures. If such procedures expect arguments on the stack, you must specifically include the prolog and epilog code yourself.

In general, the language of a procedure affects the procedure in the manner shown in the following figure.

Language: None Basic Fortran Pascal C CPP Prolog

Argument L-R L-R L-R L-R R-L R-L R-L

ordering (Ieft-to-right, right-to-Ieft)

Who cleans PROC PROC PROC PROC CALLER CALLER CALLER up stack

(caller, procedure)

You can use the Iia command-line switch to include procedure prolog and epilog code in your listing file. This lets you see the differences between the languages.

Specifying a language modifier

See Chapter 7 for more information.

Language modifiers tell Turbo Assembler to include special prolog and epilog code in procedures that interface with Windows or the VROOM overlay manager. To use them, specify one before the procedure language in the model directive, or in the procedure header. Valid modifiers are NORMAL, WINDOWS, ODDNEAR, and ODDFAR.

Additionally, you can specify a default language modifier as a parameter of the MODEL directive. If a default language modifier exists, all procedures that don't otherwise specify a language modifier will use the conventions of the default.

Include the modifier in the procedure definition to specify the language modifier for an individual procedure. For example,

sample PROC WINDOWS PASCAL FAR iprocedure body

ENDP

- . If you don't specify a language modifier, Turbo Assembler uses the

language modifier specified in the MODEL statement. Turbo Assembler will generate the standard prolog or epilog code for the procedure if there isn't a MODEL statement, or if NORMAL is specified.

. Refer to your Windows documentation for more information on Windows procedures.

If you've selected the WINDOWS language modifier, Turbo Assembler generates prolog and epilog code that lets you call the procedure from Windows. Turbo Assembler generates special prolog and epilog code only for FAR Windows procedures. You can't call NEAR procedures from Windows, so they don't need special prolog or epilog code. Procedures called by Windows typically use PASCAL calling conventions. For example,

winproc PROC WINDOWS PASCAL FAR

ARG @@hwnd:WORD,@@mess:WORD,@@wparam:WORD,@@lparam:DWORD ibody of procedure

ENDP

The ODDNEAR and ODDFAR language modifiers are used in connection with the VROOM overlay manager. VROOM has two modes of operation:

oddnear and oddfar. You can use the /la switch option on the Turbo Assembler command line to see the prolog and epilog code that these language modifiers produce.

Im Dokument . TUrbo Assembler" (Seite 136-142)