I have problems with Instring proc.I have a table named conv and string szString.I want to take each char and look on this table if they are on table store it if not skip to next char.I have tried below code but it crashes does anyone have a idea ?I have searched examples of it in masm32 dir and found one example in COM dir and Ernie says " invoke InString, 1, pszToken, ADDR szBuffer ; === has bug preserving regs"
Here is my non working code
charecter
.data?
bfkey dd ?
.data
conv db "ABCDEF0123456789"
lea esi, szString
lea edi, szStore
conv1:
movzx edx, byte ptr
mov ,edx
invoke InString,1,ADDR conv,addr bfkey
test eax,eax
jz notpresent
movzx ecx, byte ptr
mov byte ptr ,cl
inc esi
inc edi
notpresent:
cmp byte ptr ,0
jnz conv1
mov byte ptr,0
Thanks.do a search for instring on this message board. you will find that some other people were having crashing problems too.
click here for a related post
smurf
This message was edited by smurf, on 6/28/2001 9:52:22 PM
I have posted this version before, the original InString proc had
been changed too many times and it had a difficult to find bug in
it that no-one could document so I rewrote it from scratch.
Use this algo instead of the library version, it will replace the
old one in the next update of the MASM32 library.
; ########################################################################
Istring proc startpos:DWORD,lpSource:DWORD,lpPattern:DWORD
LOCAL sLen:DWORD
LOCAL pLen:DWORD
push ebx
push esi
push edi
invoke lnstr,lpSource
mov sLen, eax ; source length
invoke lnstr,lpPattern
mov pLen, eax ; pattern length
cmp startpos, 1
jge @F
mov eax, -2
jmp isOut ; exit if startpos not 1 or greater
@@:
dec startpos ; correct from 1 to 0 based index
cmp eax, sLen
jl @F
mov eax, -1
jmp isOut ; exit if pattern longer than source
@@:
sub sLen, eax ; don't read past string end
inc sLen
mov ebx, sLen
cmp ebx, startpos
jg @F
mov eax, -2
jmp isOut ; exit if startpos is past end
@@:
mov esi, lpSource
mov edi, lpPattern
mov al, ; get 1st char in pattern
xor ecx, ecx
add ecx, startpos ; add starting offset
jmp Loop_Start
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Pre_Loop:
pop ecx ; restore ECX
inc ecx ; start on next byte
Loop_Start:
cmp al,
je Pre_Sub
inc ecx
cmp ecx, ebx
jne Loop_Start
jmp No_Match
Pre_Sub:
push ecx ; preserve ECX
mov edx, pLen
mov edi, lpPattern
Sub_Loop:
mov ah,
cmp ah,
jne Pre_Loop ; jump back on mismatch
inc ecx
inc edi
dec edx
jnz Sub_Loop ; fall through if match
pop ecx ; restore ECX
mov eax, ecx ; match
inc eax
jmp isOut
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
No_Match:
mov eax, 0
isOut:
pop edi
pop esi
pop ebx
ret
Istring endp
; ########################################################################
Regards,
hutch@pbq.com.auTwo points:
1) conv isn't null terminated.
2) you don't inc esi unless you match!
Once you reach a character that is not in the string, you will sit in an endless loop.
Mirno
I have changed my code like below but it still crashes.:(
.data
bfkey dd 0
conv db "ABCDEF0123456789"
lea esi, szString
lea edi, szStore
conv1:
movzx edx, byte ptr
mov ,edx
invoke InString,1,ADDR conv,addr bfkey
test eax,eax
jz notpresent
movzx ecx, byte ptr
mov byte ptr ,cl
notpresent:
inc esi
inc edi
cmp byte ptr ,0
jnz conv1
mov byte ptr,0
invoke SetDlgItemTextA, _hWin, EDIT_KEY, edi
Two more things (shouldn't fix the crashing):
1) You must only increment edi when it is present (otherwise you'll get holes in the output), but increment esi no matter what!
2) When you invoke SetDlgItemText you do so with edi pointing at the end (the null terminator) of your stored string!
This shouldn't fix the crashing though!
Can you find out where it is crashing in the exe? Are you sure it is in that function, or is it in the InString itself?
Could it even be something like you've stored the strings in the code section, and it is read only?
Mirno
LaptoniC,
U can try this1
.data
;bfkey dd 0
;conv db "ABCDEF0123456789"
szString db "Blah, 23424bla",0
szStore db 20 dup (0)
Groups dd "A","F" ; 1st group -> "A" to "F"
dd "0","9" ; 2nd group -> "0" to "9"
; ..... ;
; ..... ; N group -> ...
nGroups dd 2 ; Number of Groups
.code
push esi ; save some registers
push edi ;
push ebx ;
push ebp ;
lea esi,Groups ;
mov edx,nGroups ;
lea ebx,szStore ;
lea edi,szString ;
push ebx ; save -> szStore
xor eax, eax ;
jz Loop2 ; jmp to Loop2
NotPresent: ;
inc ecx ;
cmp ecx, edx ; edx= nGroups
jnl Loop2 ;
Loop1: ;
push edx ; save edx= nGroups
mov ebp, ;
mov edx,;
sub ebp,eax ;
sub edx,eax ;
xor ebp,edx ; check sign
pop edx ; restore edx= nGroups
jns NotPresent ;
mov ,al ; ebx->szStore
inc ebx ;
Loop2: ;
xor ecx, ecx ; reset index
mov al, ; edi->szString
inc edi ;
test eax,eax ; end of szString ?
jnz Loop1 ;
mov ,al ; ebx->szStore -> zero end
pop edx ; restore -> szStore for SetDlgItemTextA
pop ebp ; restore some registers
pop ebx ;
pop edi ;
pop esi ;
invoke SetDlgItemTextA, _hWin, EDIT_KEY, edx
Thanks for the help.
buliaNaza;
Is your code only applicable to ABCDEF1234567890 or can it be applied to string like "XB901QKMWSTY" ? and how ?
I have found the bugs in my code.Main bug resides in Instring proc.
conv1:
movzx edx, byte ptr
mov ,edx
push esi ;if you dont save them they change :(
push edi
invoke InString,1,ADDR conv,addr bfkey
pop edi
pop esi
test eax,eax
jz notpresent
mov al, byte ptr
mov byte ptr ,al
inc edi
notpresent:
inc esi
cmp byte ptr ,0
jnz conv1
mov byte ptr ,0
invoke SetDlgItemTextA, _hWin, EDIT_KEY, addr szStore
LaptoniC,
I'm sorry! I don't test my proggi and I have some errors....
1. mov ebp, ; wrong
mov edx,; wrong
mov ebp, ; correct
mov edx,; correct
2. Groups dd "@","G" ; 1st group -> "A" to "F"
; (@ is prev for "A", "G" is next for "F"
dd 2Fh, 3Ah ; 2nd group -> "0" to "9"
; (2Fh is prev for "0", 3Ah is next for "9"
Example:
1. "X B 901QKM W ST Y" -> "B WXY 01 9 Q K M" -> 7 groups
Groups dd "A","C" ; 1st group -> "B"
; ("A" is prev for "B", "C" is next for "B"
dd "V","Z" ; 2nd group -> "W" to "Y"
; ("V" is prev for "W", "Z" is next for "Y"
.........
.........
nGroups dd 7 ; Number of Groups
Is your proc just find if desired substring in string or give its position also.As far as I understood, in your code you mix the order of my conv.Sorry I am newbie
LaptoniC,
I have a table named conv and string szString.I want to take each char and look on this table if they are on table store it if not skip to next char.
The "right" usage of Instring proc is to search a phrase, "Sunday" as example,
rather 1 byte, "9" as example, in a buffer with bytes to be searched through..
So, U don't need to look for substring in string and/or its position cos it is bit more slowly..
U want to rewrite "correct" bytes only from the string (szString) to new location (szStore).
"Correct" bytes are from table conv.
Plz, read the topic "Test a value inside a range" in Algorithms to learn more about my proc...
Example Continued:
1. "X B 901QKM W ST Y" -> "B WXY 01 9 Q K M" -> 7 groups
Groups dd "A","C" ; 1st group -> "B"
; ("A" is prev for "B", "C" is next for "B"
dd "V","Z" ; 2nd group -> "W" to "Y"
; ("V" is prev for "W", "Z" is next for "Y"
dd 2Fh,"2" ; 3rd group -> "0" to "1"
; (2Fh is prev for "0", "2" is next for "1"
dd "8",3Ah ; 4th group -> "9"
; ("8" is prev for "9", 3Ah is next for "9"
dd "P","R" ; 5th group -> "Q"
; ("P" is prev for "Q", "R" is next for "Q"
dd "J","L" ; 6th group -> "K"
; ("J" is prev for "K", "L" is next for "K"
dd "L","N" ; 6th group -> "K"
; ("L" is prev for "M", "N" is next for "M"
nGroups dd 7 ; Number of Groups
Thanks for the help.As you have asaid because I am scanning just one byte using Instring is time consuming.I have found a instruction repnz scasb.Can anyone give me an example for this.I learned that it scans byte in eax in edi? for ecx times..Should I pass every char one by one and increment at every loop or is there any simple way for this.
LaptoniC,
What I don't properly understand is what you are trying to do with
the BYTE sequence.
Scanning a a byte sequence for a set of seperate characters is not
that hard to do but I need some idea of what you want to do with it.
You are better to use later type instructions as they are faster
and cleaner code, You can scan for 1 or more bytes by using code like,
mov al,
inc esi
and either scan the source a lot of times or test each character
a lot of times. Just let us know what you are trying to do and probably
someone can help you.
Regards,
hutch@pbq.com.auOf course I can take a char one by one and compare it.However I just want to learn this scasb instruction.I saw in my asm book that repnz scasb is being used.I want to type less code.I saw some scanning function which uses repnz scasb and loadsb but I forgot where I saw and I didnt understood it.Thanks.
LaptoniC, here is an example that searches for the DWORD 'A' to 'E' that is passed to the PROC:
.CONST
cSearch DWORD 'A',
'B',
'C',
'D',
'E'
DWORD It_was_an_A,
It_was_an_B,
It_was_an_C,
It_was_an_D,
It_was_an_E
.CODE
cSearchCode PROC xChar:DWORD
push edi ;just so that windows will like us.
mov eax,xChar
mov edi,OFFSET cSearch ;address of string to search
mov ecx,LENGTHOF cSearch ;number of elements to look through
repne scasd
;Did we exit because of a match?
jne Return
;EDI points to the value after the one that was equal!
call DWORD PTR
Return:
pop edi ;the things we do for windows... :)
ret
cSearchCode ENDP
;These have to be outside the PROC because 'ret' means something
;different inside the PROC.
It_was_an_A:
ret
It_was_an_B:
ret
It_was_an_C:
ret
It_was_an_D:
ret
It_was_an_E:
ret
...example of it's use:
mov eax, 'A'
;execute the code for an 'A'
invoke cSearchCode, eax
This message was edited by bitRAKE, on 7/1/2001 7:35:58 PM