Using PROTO and INVOKE to Call a C Function from MASM

This article was previously published under Q73407
Retired KB Content Disclaimer
This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.
With the Microsoft Macro Assembler (MASM) version 6.0, the coding fora procedure call may be simplified by the use of the PROTO and INVOKEdirectives. These directives handle many of the details, such aspushing the parameters on the stack in the correct order, generatingthe correct external references, coercing arguments to the correctsize, and cleaning up the stack (if required) after the functionterminates.

The two sample programs below illustrate how a C function is calledfrom MASM, both with and without the PROTO and INVOKE directives.Sample Code 1 calls the C printf() function using the conventionalmethod of coding. Sample Code 2 shows the simplified call to the samefunction through the use of PROTO and INVOKE.
PROTO defines a prototype for a procedure much the way a functionprototype works in C. This is the syntax for PROTO:
   label PROTO [distance] [langtype] [,[parameter]:tag]				
The PROTO statement is used by the assembler to check parameter typesand quantity along with indicating the naming convention for thefunction. Arguments for the function are indicated by listing thetype, and optionally, a parameter name. For example,
   myfunc PROTO C arg1:SWORD, arg2:SBYTE				
This indicates that the function myfunc takes two arguments. The firstis a signed word, the second is a signed byte. If you need a variableargument list, you use the type VARARG.

INVOKE actually generates the code to call the function. You must havedefined the function previously with either a PROC, an EXTERNDEF, aTYPEDEF, or a PROTO statement. This is the syntax for INVOKE:
   INVOKE expression [,arguments]				
Because the assembler knows what the function is expecting in the wayof arguments and calling convention, it can take the arguments passedin the INVOKE statement and push them on the stack in the correctorder, call the function using the required function name, and cleanup the stack afterwards (if required by the calling convention used).

If an argument passed by INVOKE is smaller than the type specified inthe PROTO statement, MASM does a type conversion. It widens theargument in the PROTO statement to match that in the INVOKE statement(for example, SBYTE to SWORD). These types of conversions use the AXand DX registers on the 8086 and 8088 and the EAX and EDX registers onthe 80386/80486. Because these registers are effectively overwritten,you should take care to avoid using these registers to pass arguments.

The language type for the function determines the naming and callingconventions. In addition to the language type in the PROTO statement,the language type can be set by the .MODEL directive, the OPTIONLANGTYPE:, or by the command line switches /Gc (for Pascal) and /Gd(for C). There is a table of the various language conventions providedin Help.

Sample Code 1

; Assemble options needed: /MX          .MODEL small,c             ; The "c" langtype prepends                                     ; labels with an underscore.     ;-----for OS/2-------     ;INCLUDELIB OS2.LIB     ;INCLUDE    OS2.INC     ;--------------------EXTRN     _acrtused:NEAREXTRN     printf:NEAR          .DATAfmtlist   db     "%s, %d, %lu", 0Ah,0string_1  db     "signed byte and unsigned double word", 0data_1    db     -2data_2    dd     0FFFFFFFFh          .CODEmain      PROC          push   word ptr data_2+2   ; push the high word of data_2          push   word ptr data_2     ; push the low word of data_2          mov    al,data_1          cbw                        ; converts data_1 to a word          push   ax          mov    ax,offset string_1  ; load the address of string_1          push   ax                  ; push the address on the stack          lea    ax,fmtlist          ; load the address of fmtlist          push   ax                  ; push the address on the stack          call   printf              ; call the C library function          add    sp,0Ah              ; adjust the stackpointermain      ENDP          ret          end				

Sample Code 2

; Assemble options needed: none          .MODEL small,c    ;-----for OS/2--------|    ;.MODEL small,c,os_os2|    ;INCLUDELIB OS2.LIB   <---Not needed if "os_os2" indicated. The    ;INCLUDE    OS2.INC   |   assembler knows to look for os2.lib    ;---------------------|   in the path set by the lib environment    ;                     |   variable.EXTERNDEF _acrtused:WORDprintf    PROTO arg1:Ptr Byte, printlist: VARARG;The first argument is a pointer to a string. The second is a keyword; that permits a variable number of arguments.          .STACK 100h          .DATAfmtlist   BYTE   "%s, %d, %lu", 0Ah,0string_1  BYTE   "signed byte and unsigned double word", 0data_1    SBYTE  -2data_2    DWORD  0FFFFFFFFh          .CODEmain      PROCINVOKE    printf, ADDR fmtlist, ADDR string_1, data_1, data_2main      ENDP          ret          end				
kbinf 6.00 6.00a 6.00b s_c

Article ID: 73407 - Last Review: 10/20/2003 23:29:30 - Revision: 2.0

Microsoft Macro Assembler 6.0 Standard Edition, Microsoft Macro Assembler 6.0a, Microsoft Macro Assembler 6.0b

  • KB73407