7.3.6 Declaring Procedure Prototypes

MASM 6.0 provides a new directive, INVOKE, to handle many of the details important to procedure calls, such as pushing parameters according to the correct calling conventions. In order to use INVOKE, the procedure called must have previously been declared with a PROC statement, an EXTERNDEF (or EXTERN) statement, or a TYPEDEF. You can also place a prototype defined with PROTO before the INVOKE if the procedure type does not appear before the INVOKE. Procedure prototypes defined with PROTO inform the assembler of types and numbers of arguments so the assembler can check for errors and provide automatic conversions when INVOKE calls the procedure.

Summary: Place prototypes after data declarations or in a separate include file.

Prototypes in MASM perform the same function as prototypes in the C language and other high-level languages. A procedure prototype includes the procedure name, the types, and (optionally) the names of all parameters the procedure expects. Prototypes are usually placed at the beginning of an assembly program or in a separate include file. They are especially useful for procedures called from other modules and other languages, enabling the assembler to check for unmatched parameters. If you write routines for a library, you may want to put prototypes into an include file for all the procedures used in that library. See Chapter 8, “Sharing Data and Procedures among Modules and Libraries,” for more information about using include files.

Declaring procedure prototypes is optional. You can use the PROC directive and the CALL instruction, as shown in the previous section.

In MASM 6.0, using the PROTO directive is one way to define procedure prototypes. The syntax for a prototype definition is the same as for a procedure declaration (see Section 7.3.3, “Declaring Parameters with the PROC Directive”), except that you do not include the list of registers, prologuearg list, or the scope of the procedure.

Also, the PROTO keyword precedes the langtype and distance attributes. The attributes (like C and FAR) are optional, but if not specified, the defaults are based on any .MODEL or OPTION LANGUAGE statement. The names of the parameters are also optional, but you must list parameter types. A label preceding :VARARG is also optional in the prototype but not in the PROC statement.

If a PROTO and a PROC for the same function appear in the same module, they must match in attribute, number of parameters, and parameter types. The easiest way to create prototypes with PROTO for your procedures is to write the procedure and then copy the first line (the line that contains the PROC keyword) to a location in your program that follows the data declarations. Change PROC to PROTO and remove the USES reglist, the prologuearg field, and the visibility field. It is important that the prototype follow the declarations for any types used in it to avoid any forward references used by the parameters in the prototype.

The prototype defined with PROTO statement and the PROC statement for two procedures are given below.

; Procedure prototypes

addup PROTO NEAR C argcount:WORD, arg2:WORD, arg3:WORD

myproc PROTO FAR C, argcount:WORD, arg2:VARARG

; Procedure declarations

addup PROC NEAR C, argcount:WORD, arg2:WORD, arg3:WORD

myproc PROC FAR C PUBLIC <callcount> USES di si,

argcount:WORD,

arg2:VARARG

When you call a procedure with INVOKE, the assembler checks the arguments given by INVOKE against the parameters expected by the procedure. If the data types of the arguments do not match, MASM either reports an error or converts the type to the expected type. These conversions are explained in the next section.