Ok, I tried to use the PROC statement to define my routine's parameter, but have run into a problem. Its dereferencing my parameters for me. This may be a very good thing (I just discovered it), but it took me by surprise. The funny thing is that when I use the PASCAL language passing conventions, it doesn't appear to dereference.
Is there a way to use STDCALL and not have it dereferenced? Which language passing parameter is considered the best (is there one).
Thanks - Newbie Jack:confused:
Is there a way to use STDCALL and not have it dereferenced? Which language passing parameter is considered the best (is there one).
Thanks - Newbie Jack:confused:
[size=9]
;Purpose: Swap Parameter1 & Parameter2 values passed by reference to this routine
;vb code -> res& = CallWindowProc(VarPtr(InCode(1)), VarPtr(lng1&),VarPtr(Lng2&), 3&, 4&)
;where Long1 is pointer to parameter1 and Long2 is pointer to paremeger2
.586
.model small
.code
SwapArgs PROC STDCALL long1:dword, long2:dword, long3:dword, long4:dword
;long1 equ[ebp+8]
;long2 equ[ebp+12]
;long3 equ[ebp+16]
;long4 equ[ebp+20]
;Save Registers into Stack
push ebp
mov ebp,esp
push ebx
push ecx
;Save contents of long1 to ecx
mov ebx,long1 ;load addr(long1) into ebx
mov ecx,[ebx] ;move value into ecx
;Save contents of long2 to eax
mov ebx,long2
mov eax,[ebx] ;eax now contains value of long2
;put contents of long2 into long1
mov ebx,long2 ;Load addr(long2) into ebx
mov [ebx],ecx ;put eax (long1 value) into long1
mov eax,ecx
;put contents of long1 into long2
;mov ebx,long1
;mov ecx,eax
;mov [ebx],ecx
;mov [ebx],eax
;Restore Registers from Stack
pop ecx
pop ebx
mov esp,ebp
pop ebp
;Finish
ret 16
SwapArgs endp
END
[/SIZE]
Disassemble you code, masm creates:
push ebp
mov ebp,esp
automatically when you create a new procedure.
push ebp
mov ebp,esp
automatically when you create a new procedure.
Jack,
I am just guessing but if you are passing the parameter in basic, pass it ByVal (BY VALUE) and you will get what you pass at the other end. If you pass it by the default ByRef (BY REFERENCE) you will need to dereference it at the other end.
Good luck.
hutch@movsd.com
I am just guessing but if you are passing the parameter in basic, pass it ByVal (BY VALUE) and you will get what you pass at the other end. If you pass it by the default ByRef (BY REFERENCE) you will need to dereference it at the other end.
Good luck.
hutch@movsd.com
hutch,
Great to see you are familiar with Visual Basic(VB):). I'm passing it ByRef because I want to change its value and then have the VB calling routine received a changed value. In this learning exercise I'm simply swapping the first parameter with the second - changing their values.
I guess I really confused as to how to get the address of a parameter when I've defined them with the PROC. Can I get its address or is there a way to modify the PROC statement to NOT DEREFERENCE it? The memory addressing is a bit confusing to me.
Thanks - Jack
Great to see you are familiar with Visual Basic(VB):). I'm passing it ByRef because I want to change its value and then have the VB calling routine received a changed value. In this learning exercise I'm simply swapping the first parameter with the second - changing their values.
I guess I really confused as to how to get the address of a parameter when I've defined them with the PROC. Can I get its address or is there a way to modify the PROC statement to NOT DEREFERENCE it? The memory addressing is a bit confusing to me.
Thanks - Jack
Thanks everyone for the help. I figured it out.
Jack
This works:
Jack
This works:
[size=9]
;Purpose: Swap Parameter1 & Parameter2 values passed by reference to this routine
;vb code -> res& = CallWindowProc(VarPtr(InCode(1)), VarPtr(lng1&),VarPtr(Lng2&), 3&, 4&)
;where Long1 is pointer to parameter1 and Long2 is pointer to paremeger2
.586
.model small
.code
SwapArgs PROC STDCALL USES ebx ecx edx long1:dword, long2:dword, long3:dword, long4:dword
;Save contents of long1 to ecx
mov ebx,long1 ;load addr(long1) into ebx
mov ecx,[ebx] ;move value into ecx
;Save contents of long2 to eax
mov ebx,long2
mov eax,[ebx] ;eax now contains value of long2
;put contents of long2 into long1
mov ebx,long2 ;Load addr(long2) into ebx
mov [ebx],ecx ;put eax (long1 value) into long1
;put contents of long1 into long2
mov ebx,long1
mov [ebx],eax
;Finish Up
ret 16
SwapArgs endp
END
[/SIZE]
Just use ret, masm will covert it itself using the appropriate value...
It can avoid errors if you say add, or remove a variable from the PROC, and forget to change the ret value!
Mirno
It can avoid errors if you say add, or remove a variable from the PROC, and forget to change the ret value!
Mirno