i have to admit that i have never tried INVOKE in 16-bit code, but there's no reason it shouldn't work
that's because, in DOS days, i used MASM v 5.1 which did not support INVOKE
INVOKE'd functions require a PROTOtype, generally placed early in the file
(well - they require one if the INVOKE is to appear before the PROC)
the prototype tells the assembler how many arguments to expect, and their sizes
it may also tell the assembler which type of calling convention to use and the distance (NEAR or FAR)
for 32-bit programs, everything is NEAR, and the default is StdCall (defined in the .MODEL directive)
i am not sure how that works in 16-bit code
you'll have to consult the MASM manual for details
MyFunc PROTO <dist> <type> :WORD,:WORD,:WORD<dist> would be replaced with NEAR or FAR
<type> would be C, Pascal, Basic, StdCall, SysCall, etc
the default depends on the .MODEL and OPTION's (read the manual)
let's assume you use NEAR and StdCall.....
then, in the code section...
.CODE
INVOKE MyFunc,arg1,arg2,arg3
and, the function
MyFunc PROC NEAR StdCall _arg1:WORD,_arg2:WORD,_arg3:WORD
mov ax,_arg1
mov cx,_arg2
mov dx,_arg3
;
;
ret
MyFunc ENDP
because you use NEAR and StdCall, the actual code generated might look like this
push arg3
push arg2
push arg1
call MyFunc
and....
MyFunc:
push bp
mov bp,sp
mov ax,[bp+4]
mov cx,[bp+6]
mov dx,[bp+8]
;
;
leave
ret 6
the LEAVE instruction is essentially the same as
mov sp,bp
pop bp
RET 6 returns and POP's 6 bytes off the stack (the passed arguments)
the behaviour is different for other <dist> and <type> parameters