ARG              Set up argument stack                              Directive

ARG argument [,argument] ... [=symbol] [RETURNS argument [,argument]]

Sets up arguments on the stack for procedures. Each argument is
assigned a positive offset from the BP (EBP) register, presuming that
both the return address of the procedure call and the caller's BP have
been pushed onto the stack already.

The procedure's language convention determines whether or not the
arguments will be assigned in reverse order on the stack. You should
always list arguments in the ARG statement in the same order they
would appear in a high-level language declaration of the procedure.


Example: proc func1 near
arg A:word, B:dword:2, C:byte = D
local @@x:dword, @@y:word:2 = @@z

defines A as [BP+4], B as [BP+6], C as [BP+14], and
D as 12; @@x is [BP-2], @@y is [BP-6], and @@z is 8.

If you end the argument list with an equal sign (=) and a symbol, that
symbol will be equated to the total size of the argument block in
bytes.

Note that byte-sized arguments are considered to take 2 bytes of stack
space, unless an explicit count field is specified.

All argument names (whether passed arguments (ARG), returned arguments
(RETURNS), or local variables (LOCAL)) are global in scope, unless you
give them names prepended with the local symbol prefix.

──────────────────────────────────────────────────────────────────────

The optional RETURNS keyword introduces one or more arguments that
won't be popped from the stack when the procedure returns to its
caller. Normally, if you specify the language as PASCAL or TPASCAL when
using the MODEL directive, all arguments are popped when the procedure
returns. The RETURNS keyword generates BP-relative equates following
the C calling convention even if a procedure has a Pascal language
modifier. If RETURNS is used without ARG or LOCAL, the stack frame
isn't set up.


Example: ; Pascal declaration:
; Function FillChar(len:word; khar:byte) : string; external
procdesc FillChar pascal far :word, :byte, :dword
proc FillChar
arg len:word, khar:byte returns result_ptr:dword
les di,[result_ptr] ; Passed by TP
mov ax,[len]
sub ah,ah ; String limit = 255
cld
stosb ; Store length byte
mov cx,ax
mov al,[khar]
rep stosb ; Fill string
RET ; I.e. RETF 4
endp


Example: procdesc qtest pascal :dword
proc qtest
arg returns @@pt:dword
local dummy :word ; Need this to set up BP
;... ; correctly (generate
; enter/leave)

──────────────────────────────────────────────────────────────────────

Example: ideal
p186
model small, nolanguage
codeseg
proc picklist Pascal near ; Frame after ENTERing proc
arg ztitle_ptr :dword, \ [bp + 0Eh]
zlist_ptr :dword, \ [bp + 0Ah]
num_items :word, \ [bp + 08h]
upper_left :word, \ [bp + 06h]
max_width :word \ [bp + 04h]
returns top_item :word, \ [bp + 12h] ; (*)
pick_item :word ; [bp + 14h]
local saved_csr :word, \ [bp - 04h]
bar_pos :word ; [bp - 02h]
uses ds ; ([bp + 02h] = saved IP)
ASSUME ds:dgroup ; ([bp] = saved BP)
;...
RET ; I.e. RETN 0Eh
endp
;...
; Calling from assembler:
push [picked_item] ; Push VAR parameters
push [first_item]
call picklist Pascal, \
ds dx, \
es di, \
[items],\
[ul], \
[zwidth]
pop [first_item] ; Clean up stack
pop [picked_item] ; and update variables
;...

(*) Note that RETURNS parameters are always
assigned "C-style" BP-relative offsets.

──────────────────────────────────────────────────────────────────────

Similar example using C language modifier:

ideal
p186
model small, nolanguage
codeseg
proc picklist C near ; Frame after ENTERing proc
arg ztitle_ptr :dword, \ [bp + 04h]
zlist_ptr :dword, \ [bp + 08h]
num_items :word, \ [bp + 0Ch]
upper_left :word, \ [bp + 0Eh]
max_width :word \ [bp + 10h]
returns top_item :word, \ [bp + 12h] ; (*)
pick_item :word ; [bp + 14h]
local saved_csr :word, \ [bp - 02h]
bar_pos :word ; [bp - 04h]
uses ds,si,di ; ([bp + 02h] = saved IP)
ASSUME ds:dgroup ; ([bp] = saved BP)
;...
RET ; I.e. RETN 00h
endp
;...
; Calling from assembler:
push [picked_item] ; Push VAR parameters
push [first_item]
call picklist C, \
ds dx, \
es di, \
[items],\
[ul], \
[zwidth]
pop [first_item] ; Clean up stack
pop [picked_item] ; and update variables
;... ; (TASM auto-generates
; ADD SP,0Eh after CALL)