I had the problem with the procedure:
Print PROC
ARG pStr:WORD
mov si, pStr
PrintLoop:
lodsb
cmp al, 0 ; End of line?
je PrintRet
int 29h ; Print AL byte
jmp PrintLoop
PrintRet:
ret
Print endp
Calling code:
push offset FileName
call Print
Result: it does not work as expected.
I have found some info about ARG directive:
Article #19021: TP 5.0/TASM – ARG DIRECTIVE SYMBOLIC REFERENCES
Technical Notes Database
TN4021C.txt TP 5.0/TASM - ARG DIRECTIVE SYMBOLIC REFERENCES
Category : Pascal
Platform : All
Product : TD 1.x 2.0
Description:
Q. I am using the Arg directive to create symbolic references to
variables on the stack. I am not getting the correct values
I should in the Assembler routine. What am I doing wrong?
A. It is easier if remember a few points about the Arg directive.
First, the Arg directive always adjusts for a near or far
call. If you have a proc definition like:
myproc proc far
the Arg directive will take into account the four (4) byte return
address on the stack. If your definition looks like:
myproc proc near
the Arg directive will adjust for a two (2) byte return
address on the stack. The second thing to remember is that
the Arg directive always assumes that you will push BP onto
the stack first and thus, will add two bytes to the size of
the return address. For a far return the total will be six
bytes and for a near return the total will be four bytes. The
third point to remember about the Arg directive itself is that
the leftmost symbol in the Arg list will be nearest the top of
the stack. Finally, remember that for each subsequent symbol
to the right, a number equal to the number of bytes on the
stack occupied by the symbols to the left will be added to the
BP register.
Consider the following examples:
myproc proc near
arg first:word, second:word
push bp
mov bp,sp
The distance is near, a two byte return address, and the BP is
assumed to pushed onto the stack. Thus, any reference to
first is equivalent to [BP + 04H]. Since first is a word it
occupies two bytes on the stack. Thus second evaluates to [BP
+ 04H + 02H] or [BP + 06H].
myproc proc far
arg first:word, second:word
push bp
mov bp,sp
The distance is far, a four byte return address, and the BP is
assumed to be pushed onto the stack. Thus, any reference to
first if equivalent to [BP + 06H]. Since first is a word, it
occupies two bytes on the stack. Thus, second evaluates to
[BP + 06H + 02H] or [BP + 08H].
myproc proc far
arg first:near ptr word, second:word
push bp
mov bp,sp
The distance is far, a four byte return address, and the BP is
assumed to be pushed onto the stack. Thus any reference to
first is equivalent to [BP + 06H]. Since first is a near
pointer it occupies two bytes on the stack. Thus second
evaluates to [BP + 06H + 02H] or [BP + 08H].
myproc proc far
arg first:byte, second:word
push bp
mov bp,sp
The distance is far, a four byte return address, and the BP is
assumed to be pushed onto the stack. Thus, any reference to
first is equivalent to [BP + 06H]. Although first is a byte
value it occupies two bytes on the stack. Thus, second
evaluates to [BP + 06H + 02H] or [BP + 08H].
myproc proc far
arg first:byte:1, second:word
push bp
mov bp,sp
The distance is far, a four byte return address, and the BP is
assumed to be pushed onto the stack. Thus, any reference to
first is equivalent to [BP + 06H]. Although first is a byte
value it occupies two bytes on the stack. To force it to use
only one byte we must use the :1 after the word byte. Second
evaluates to {BP + 06H + 01H] or [BP + 07H]. Note that the
type of variables must match the types of those that appear in
the high level language call.
Reference:
7/2/98 10:45:32 AM
Last Modified: 01-SEP-99
Source note: Article #19021: TP 5.0/TASM – ARG DIRECTIVE SYMBOLIC REFERENCES
Print PROC
ARG pStr:WORD
push bp ; ADDED
mov bp, sp ; ADDED
mov si, pStr
PrintLoop:
lodsb
cmp al, 0 ; End of line?
je PrintRet
int 29h ; Print AL byte
jmp PrintLoop
PrintRet:
pop bp ; ADDED
ret
Print endp