Hi There,
I program mostly in VB, and would like to know how to create a function which returns a number or a string similiar to VB like below:
VB CODE EXAMPLE BELOW:
'Function makes a comparison based on giving text and then returns the value...
Public Function FunctionName(Text AS String)
If Text = "Good" then
FunctionName() = "Text Found"
else
FunctionName() = "Text not Found"
End If
End Sub
-OR-
Public Function FunctionName(Text AS String)
If Text = "Good" then
FunctionName() = 817
else
FunctionName() = 978
End If
End Sub
Anyone know how to do it?
I program mostly in VB, and would like to know how to create a function which returns a number or a string similiar to VB like below:
VB CODE EXAMPLE BELOW:
'Function makes a comparison based on giving text and then returns the value...
Public Function FunctionName(Text AS String)
If Text = "Good" then
FunctionName() = "Text Found"
else
FunctionName() = "Text not Found"
End If
End Sub
-OR-
Public Function FunctionName(Text AS String)
If Text = "Good" then
FunctionName() = 817
else
FunctionName() = 978
End If
End Sub
Anyone know how to do it?
With procedures a program normally expects numbers to be returned in the eax register. In any language a function puts the return value into the eax register before it returns. In the case of strings it is actually a pointer to the string that is being returned not the actual text, that pointer is returned in eax as well. When you specify AS STRING you are informing VB that the number returned is a pointer to a NULL terminated string and not an actual number. So, to return a number or a string...
NUMBER:
mov eax,NUMBER
ret
STRING
lea eax,STRING
ret
or
mov eax,OFFSET STRING
ret
Donkey
NUMBER:
mov eax,NUMBER
ret
STRING
lea eax,STRING
ret
or
mov eax,OFFSET STRING
ret
Donkey
Thank you Donkey, you hit the nail on the head, or as 1 might say to a donkey, you sure pinned the tail on that one, hehe.
That bit of information is hard to come by without all the details.
That bit of information is hard to come by without all the details.
Knight Chat X,
i am just gonna nit-pick here: your VB is a bit dodgy. Because you didn't declare a return type from your functions, the returned value is cast as a variant. Variants are convenient, but evil ;)
OK, i feel better now :) If you do a search, you will find a couple of fairly detailed posts i have done explaining how to pass values from VB to asm and back, if you read these it may help with your understanding, and enable you to use asm dlls from a VB gui.
i am just gonna nit-pick here: your VB is a bit dodgy. Because you didn't declare a return type from your functions, the returned value is cast as a variant. Variants are convenient, but evil ;)
OK, i feel better now :) If you do a search, you will find a couple of fairly detailed posts i have done explaining how to pass values from VB to asm and back, if you read these it may help with your understanding, and enable you to use asm dlls from a VB gui.
When you return string like donkey has shown, make sure that returned string is not LOCAL (on stack) otherwise it becomes invalid when procedure returns.
Hi Sluggo,
Yea, I could've probably given a fuller example but figured the question was simple enuff.
Donkey hit the nail on the head, because what I was asking was how to setup a function where the return value could be passed either as a string or number, the example's he gave filled in the gap showing how a function would do a return to produce the right output.
Lastly, I'm trying to convert user defined code from VB to assembler, not use assembler through VB using a DLL or even directly.
Here's a more complete modification of the first post:
Public Function KCX_Test(Text As String) As String
If Text = "Good" then KCX_Test() = "Text Found"
End Sub
Yea, I could've probably given a fuller example but figured the question was simple enuff.
Donkey hit the nail on the head, because what I was asking was how to setup a function where the return value could be passed either as a string or number, the example's he gave filled in the gap showing how a function would do a return to produce the right output.
Lastly, I'm trying to convert user defined code from VB to assembler, not use assembler through VB using a DLL or even directly.
Here's a more complete modification of the first post:
Public Function KCX_Test(Text As String) As String
If Text = "Good" then KCX_Test() = "Text Found"
End Sub
sluggy said
Knight Chat X,
i am just gonna nit-pick here: your VB is a bit dodgy. Because you didn't declare a return type from your functions, the returned value is cast as a variant. Variants are convenient, but evil ;)
OK, i feel better now :) If you do a search, you will find a couple of fairly detailed posts i have done explaining how to pass values from VB to asm and back, if you read these it may help with your understanding, and enable you to use asm dlls from a VB gui.
Knight Chat X,
i am just gonna nit-pick here: your VB is a bit dodgy. Because you didn't declare a return type from your functions, the returned value is cast as a variant. Variants are convenient, but evil ;)
OK, i feel better now :) If you do a search, you will find a couple of fairly detailed posts i have done explaining how to pass values from VB to asm and back, if you read these it may help with your understanding, and enable you to use asm dlls from a VB gui.
Also he has end sub instead of end function. ;)
And as for the Variants are evil... I havea book here from MS that says to use variants and they are not evil they are actually faster...
Next time, I'm just gonna type the code in the VB IDE that way there's syntax checking, nobody's perfect, haha.
=oP
=oP
So you are trying to convert:
to assembly? If so, it isn't to hard... I will scrounge up some code, post it and explain it to you.
Public Function KCX_Test(Text As String) As String
If Text = "Good" Then
KCX_Test = "Text Found"
Else
KCX_Test = "Text NOT Found"
End If
End Function
to assembly? If so, it isn't to hard... I will scrounge up some code, post it and explain it to you.
Yep
Thanks for the help guys I appreciate it.
Thanks for the help guys I appreciate it.
Ok, for testing, add the following to the .data section (using masm here)
and this is the converted function... I was too lazy so I used the api:
and to call it we pass the address of the string to check:
Make sense?
sGood BYTE 'Good', 0
sFound BYTE 'Text Found', 0
sNotFound BYTE 'Text NOT Found', 0
sBadText BYTE 'Bad', 0
and this is the converted function... I was too lazy so I used the api:
KCX_Test proc pszText:DWORD
push offset sGood ; Compare string
push pszText ; String to compare
call lstrcmpi
test eax, eax
jz Good ; It matches
jmp NoGood ; No Match
Good:
lea eax, sFound ; return the address of string
ret
NoGood:
lea eax, sNotFound ; same here
ret
KCX_Test endp
and to call it we pass the address of the string to check:
push offset sGood ; need address to string
call KCX_Test
push 0
push 0
push eax ; address of returned string
push 0
call MessageBox
push offset sBadText ; need address to string
call KCX_Test
push 0
push 0
push eax ; address of returned string
push 0
call MessageBox
Make sense?
Knight Chat X,
Here's a quick way to do it using the CompareString function from the API. It's generally not as fast as comparable handwritten functions but it is fairly efficient when no parameters are specified
Invoke KCX_Test,ADDR MyString
Donkey
Here's a quick way to do it using the CompareString function from the API. It's generally not as fast as comparable handwritten functions but it is fairly efficient when no parameters are specified
.Const
LOCALE_SYSTEM_DEFAULT equ 2048
.data
lpszGOOD BYTE "Good",0
lpszFOUND BYTE "Text Found",0
lpszNOTFOUND BYTE "Text NOT Found",0
.code
start:
; lots of stuff here to do with your window and exactly what is calling the procedure etc...
[b]KCX_Test proc lpszTEXT:DWORD
invoke CompareString,LOCALE_SYSTEM_DEFAULT,0,lpszTEXT,-1,ADDR lpszGOOD,-1
cmp eax,2
jne @F
mov eax,OFFSET lpszFOUND
ret
@@:
mov eax,OFFSET lpszNOTFOUND
ret
KCX_Test endp[/b]
start ends
Pass the string as a pointer to the procedure like this...
Invoke KCX_Test,ADDR MyString
Donkey
;DATA
.data
scs1 BYTE "Test1",0
scs2 BYTE "Test2",0
m1Found BYTE "Match 1 Found",0
m2Found BYTE "Match 2 Found",0
mNotFound BYTE "No Match's Found",0
;PROC
;Does a text/string comparison, then return a text/string pointer in eax...
KCX_Test proc pszText:DWORD
push offset scs1 ; push compare string.
push pszText ; push string to compare.
call lstrcmpi ; call string compare api.
test eax,eax ; do comparison.
jz Match1Found ; jump if comparison match's.
jmp Check2 ; match not found so jump to next check.
Match1Found: ; match 1 found code label.
lea eax,m1Found ; put/set string pointer in the eax register.
ret ; return/exit function.
Check2: ; check 2 code label.
push offset scs2 ; push compare string 2.
push pszText ; push string to compare.
call lstrcmpi ; call string compare api.
test eax,eax ; do comparison.
jz Match2Found ; jump if comparison match's.
jmp ChecksFinished ; match not found, so do 1 last jump.
Match2Found: ; Match 2 found code label.
lea eax,m2Found ; put/set string pointer in the eax register.
ret ; return/exit function.
ChecksFinished: ; Checks Finished code label.
lea eax,mNotFound ; put/set string pointer in the eax register.
ret ; return/exit function.
KCX_Test endp
;CALL FUNCTION
push offset m2Found ;push string check pointer.
call KCX_Test ;call test function.
;VIEW TEST RESULT
push 0 ;push style.
push 0 ;push title.
push eax ;push returned string pointer.
push 0 ;push return window handle.
call MessageBox ;call function to display result.
.data
scs1 BYTE "Test1",0
scs2 BYTE "Test2",0
m1Found BYTE "Match 1 Found",0
m2Found BYTE "Match 2 Found",0
mNotFound BYTE "No Match's Found",0
;PROC
;Does a text/string comparison, then return a text/string pointer in eax...
KCX_Test proc pszText:DWORD
push offset scs1 ; push compare string.
push pszText ; push string to compare.
call lstrcmpi ; call string compare api.
test eax,eax ; do comparison.
jz Match1Found ; jump if comparison match's.
jmp Check2 ; match not found so jump to next check.
Match1Found: ; match 1 found code label.
lea eax,m1Found ; put/set string pointer in the eax register.
ret ; return/exit function.
Check2: ; check 2 code label.
push offset scs2 ; push compare string 2.
push pszText ; push string to compare.
call lstrcmpi ; call string compare api.
test eax,eax ; do comparison.
jz Match2Found ; jump if comparison match's.
jmp ChecksFinished ; match not found, so do 1 last jump.
Match2Found: ; Match 2 found code label.
lea eax,m2Found ; put/set string pointer in the eax register.
ret ; return/exit function.
ChecksFinished: ; Checks Finished code label.
lea eax,mNotFound ; put/set string pointer in the eax register.
ret ; return/exit function.
KCX_Test endp
;CALL FUNCTION
push offset m2Found ;push string check pointer.
call KCX_Test ;call test function.
;VIEW TEST RESULT
push 0 ;push style.
push 0 ;push title.
push eax ;push returned string pointer.
push 0 ;push return window handle.
call MessageBox ;call function to display result.
Save some bytes.
.data
scs1 BYTE "Test1",0
scs2 BYTE "Test2",0
m1Found BYTE "Match 1 Found",0
m2Found BYTE "Match 2 Found",0
mNotFound BYTE "No Match's Found",0
.code
KCX_Test proc pszText:DWORD
push offset scs1
push pszText
call lstrcmpi
test eax,eax
jnz Check2
Match1Found:
lea eax,m1Found
ret
Check2:
push offset scs2
push pszText
call lstrcmpi
test eax,eax
jnz ChecksFinished
Match2Found:
lea eax,m2Found
ret
ChecksFinished:
lea eax,mNotFound
ret
KCX_Test endp
;CALL FUNCTION
push offset m2Found ;push string check pointer.
call KCX_Test ;call test function.
;VIEW TEST RESULT
push 0 ;push style.
push 0 ;push title.
push eax ;push returned string pointer.
push 0 ;push return window handle.
call MessageBox ;call function to display result.
You optimized the code using jnz to replace the other jmp instructions and speed up the code, saved a few bytes, thanks... =)
btw, have I seen you somewhere before?
btw, have I seen you somewhere before?
I really don't know. I just hang around on 2 forums.