Using PROTO and INVOKE to Call a C Function from MASM
Retired KB Content Disclaimer
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.
label PROTO [distance] [langtype] [,[parameter]:tag]
myfunc PROTO C arg1:SWORD, arg2:SBYTE
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]
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
Article ID: 73407 - Last Review: 10/20/2003 23:29:30 - Revision: 2.0