Hello everybody! I'm not entirely new to assembly programming, but it's been awhile. Feel free to have a look at my example code:
include \masm32\include\masm32rt.inc
.data
item dd 10
text db 10 dup (0)
.code
start:
call main
inkey
exit
testp1 proc var: dword
mov eax, dword ptr [var]
shl eax, 1
mov dword ptr [var], eax
ret
testp1 endp
testp2 proc var: dword
mov eax, var
shl eax, 1
mov var, eax
ret
testp endp
main proc
cls
;
invoke testp, item
invoke udw2str, item, addr text
print addr text, 13, 10
;
invoke testp, addr item
invoke udw2str, item, addr text
print addr text, 13, 10
;
invoke testp, item
invoke udw2str, addr item, addr text
print addr text, 13, 10
;
invoke testp, addr item
invoke udw2str, addr item, addr text
print addr text, 13, 10
;
ret
main endp
end start
My problem is: I don't get what I expect. No matter which testp procedure I call in the main proc, I never get 20 as a result. Any help?
Note 1: The main proc refers to testp. That on can either be testp1 or testp2. Also there are plenty of calls to print. That's only for display reasons.
Note 2: I know the testp procs return the correct result in eax. But I'm going for variables/parameters to supply and receive values.
The result is in eax,not in var
testp1 proc var: dword ; Here var is a dword pushed on stack at the call,not a data.
; You can use var in the proc,but it is lost when the proc return
Quote
.LISTALL
00000000 testp1 proc var: dword
00000000 55 * push ebp
00000001 8BEC * mov ebp, esp
00000003 8B4508 mov eax, dword ptr [var]
00000006 D1E0 shl eax, 1
00000008 894508 mov dword ptr [var], eax
0000000B ret
0000000B 5D * pop ebp
0000000C C20400 * retn 4 ;content of the stack is lost
0000000F testp1 endp
I know. But suppose I supply more than one parameter to the proc. Is there a way I can use those to also receive return data, like in C or Pascal?
what you probably want to do is to pass a pointer to the variable
;###############################################################################################
INCLUDE \Masm32\Include\Masm32rt.inc
;###############################################################################################
ShftProc PROTO :LPVOID
;###############################################################################################
.DATA
dwVariable dd 4
;###############################################################################################
.CODE
;***********************************************************************************************
main PROC
print str$(dwVariable),32
INVOKE ShftProc,offset dwVariable
print str$(dwVariable),13,10,13,10
inkey
exit
main ENDP
;***********************************************************************************************
ShftProc PROC lpVar:LPVOID
mov edx,lpVar
shl dword ptr [edx],1
ret
ShftProc ENDP
;###############################################################################################
END main
That's right :t
most if not all modern compilers return a result or status in EAX when calling functions
some functions don't return any status, of course
generally speaking, if a dword result/status isn't enough room, the result is returned in variables (structures or arrays)
in ASM, we have the luxury of returning values in ECX or EDX also
some C compilers (of old) left the passed arguments on the stack - sometimes modifying their values
For a procedure to modify the value of variable it must be passed the address of the variable, and then use that address in an indirect memory operand for the instruction that modifies the variable. And to encode an instruction that uses an indirect memory operand MASM must know the size of the operand, so for SHL and similar instructions you must specify the size (as in DWORD PTR).
And the standard methods of returning values are specified in the ABI, see calling_conventions.pdf, available here:
http://www.agner.org/optimize/
Hi leghorn,
and welcome to the forum.
Gunther