To find out if param2 is used
MyFunction proc c param1:dword,param2:vararg
mov eax,ebp
add eax,4
mov eax,dword ptr [eax]
mov eax,dword ptr [eax]
and eax,0FFFFFFh
shr eax,16
.if eax==8
mov eax,param2
.endif
endp
A bit clumsy, and not foolproof, as many things can be found on the stack. Often, you would use param1 to pass the number of arguments. If you don't want that, you might try to find the return address, i.e. something between GetModuleHandle(0) and some label towards the end of your program, plus code from libraries that eventually got included. And yet, this would work only if the "true" parameters can't be in that range.
What do you want to achieve here?
It is an existing dll function that I use in some of my programs. Now I update this function and I need an additional parameter without having to modify the applications that already use it.
You could pass it in eax, ecx, edx, maybe with a simple xor check:
include \masm32\include\masm32rt.inc
.code
MyFunction proc c param1:dword ; ,param2:vararg
xor edx, eax
.if edx==12345678h
print str$(eax), 9, "valid p2", 13, 10
.else
print str$(eax), 9, "INVALID p2", 13, 10
.endif
print str$(param1), 9, "p1", 13, 10, 10
ret
MyFunction endp
start:
mov eax, 111
mov edx, eax
xor edx, 12345678h
invoke MyFunction, 777
mov eax, 222
mov edx, eax
xor edx, 12345678h
inc edx ; invalidate
invoke MyFunction, 777
exit
end start
Quote from: minor28 on November 06, 2014, 04:22:24 AMNow I update this function and I need an additional parameter without having to modify the applications that already use it.
Do not "update" the function - create a new function.
Quote from: qWord on November 06, 2014, 04:48:21 AM
Do not "update" the function - create a new function.
That's a good advice. :t
Gunther
OK, as I understand it from your answers, it's not a solution that I should use.
What if to use a simple macro?
Something like this:
MyInvoke MACRO myprocname, firstarg, secondarg:=<0>
.if secondarg
invoke myprocname, firstarg, secondarg
.else
invoke myprocname, firstarg
.endif
ENDM
this is the "inkey" macro from masm32
maybe you can get some ideas :t
inkey MACRO user_text:VARARG
IFDIF <user_text>,<NULL> ;; if user text not "NULL"
IFNB <user_text> ;; if user text not blank
print user_text ;; print user defined text
ELSE ;; else
print "Press any key to continue ..." ;; print default text
ENDIF
ENDIF
call wait_key
print chr$(13,10)
ENDM
Determining parameters during runtime :
include CheckParam.inc
CheckParam PROTO C arg1:DWORD,arglist:VARARG
SECOND_PARAM equ 2*4
RET_ADDR equ 4
.data
msg1 db 'There is no second parameter.',13,10,0
msg2 db 'The second parameter is = %u',13,10,0
.data?
buffer db 256 dup(?)
.code
start:
invoke CheckParam,9,7,3,5,1
invoke CheckParam,1,5
invoke CheckParam,10
invoke ExitProcess,0
CheckParam PROC C arg1:DWORD,arglist:VARARG
mov edx,DWORD PTR [ebp+4] ; ebp -> Return address
; The ADD command is following
; the invoke instruction
; Encoding of ADD esp,x
; 0x83 , 0xC4 , 4*x
movzx eax,BYTE PTR [edx+2]
cmp eax,SECOND_PARAM ; check for the second parameter
jae @f
invoke StdOut,ADDR msg1
ret
@@:
mov ecx,arg1
invoke wsprintf,ADDR buffer,\
ADDR msg2,\
DWORD PTR [ebp + RET_ADDR + SECOND_PARAM]
invoke StdOut,ADDR buffer
ret
CheckParam ENDP
END start
Very neat trick, Erol - thanks for sharing this :t
CheckParam PROC C arg1:DWORD,arglist:VARARG
Local v1, v2, rc:RECT ; works with locals, too
mov edx,DWORD PTR [ebp+4] ; ebp -> Return address
; The ADD command is following
; the invoke instruction
; Encoding of ADD esp,x
; 0x83 , 0xC4 , 4*x
cmp BYTE PTR [edx+2], SECOND_PARAM ; check for the second parameter
jae @f
Hi Jochen,
Thanks for the line cmp BYTE PTR [edx+2], SECOND_PARAM
That's quicker and easier.
Vortex,
What you suggest is the same as I wrote in my question. I also compare what is written in the return address "add esp,8" (0x83C408) but perhaps in a bit clumsy way.
My question remains. Is this ugly coding?
:biggrin:
I have a simple view on the beauty of coding , if it works, it works. If it works it ain't ugly. :P
Not uggly,but can be more readable
.const
Ctest PROTO C :DWORD,:VARARG
.code
invoke Ctest,0,1,2,3,4,addr recta
Ctest PROC C fixed:DWORD,item:VARARG
Local varargsize:DWORD
Local varargadr:DWORD
mov edx,[ebp+4] ;point return adress ,"ADD esp,x"
movzx eax,BYTE PTR [edx+2] ;get x
sub eax,sizeof fixed
mov varargsize,eax ;VARARG size
lea edx,fixed
add edx,sizeof fixed
mov varargadr,edx ;VARARG adress
FindeCtest:
ret
Ctest endp
Quote from: minor28 on November 07, 2014, 08:58:19 AMMy question remains. Is this ugly coding?
It is (bad style)
∞ programming.
Quote from: qWord on November 07, 2014, 10:22:49 PM
It is (bad style)∞ programming.
that's a bit exaggerated. But it's bad style. That's right.
Gunther
MINOR28,
...At least you're not getting death threats,...
That's when you can be certain that your code is ugly,...
Quote from: minor28 on November 06, 2014, 04:22:24 AM
It is an existing dll function that I use in some of my programs. Now I update this function and I need an additional parameter without having to modify the applications that already use it.
What does your solar calculations do ?
Solar calculations is a stand alone application to calculate solar data
on choosen places and choosen times.
Solar calculations. Click on a place on the google maps and the latitude, longitude, time zone, daylight saving time, time, solar elevation and solar azimuth can be read on that place. I have an updated version not published yet.
Ugly was perhaps not the right word to use. I suppose it would have been "bad style". I had a feeling that it was not a common way to code, hence my question. I will take qWord's suggestion and write a new function.
Thank you
Hi minor28,
No worries and no ugliness. With some modifications, your code will be fine. You mentioned about Solar calculations. Keep up the good work.