Oh, you seem a patient analiser.
For me is not difficult to analise assembler code, it is impossible

So i prefer to create than to analize.
However, i must have patient for to explain it.
An i will try it next time.

AL
Code: Select all
Procedure.l CountStrings(a.s,s.s)
!cld ;clear DF (Direction Flag)
!mov edi,dword[esp] ;load edi register with pointer to first string
!mov esi,dword[esp+4] ;load esi register with pointer to second string (the string to search)
!xor eax,eax ;set eax register to NULL
!mov bl,al ;set bl register to NULL
!mov edx,esi ;save this value in edx to avoid, as much as possible, to have to read data from memory in the main loop.
!;If any of two strings is empty then end program and matches found is 0:
!cmp byte[esi],bl ;test if second string is empty
!jz fin ;if so, then end
!;Main loop:
!mainloop:
!cmp byte[edi],bl ;check if end of first string is reached
!jz fin ;if not reached then end
!mov esi,edx ;restore this
!cmpsb ;what this instruction do is just compare byte[edi] with byte[esi] and increment edi and esi values by 1
!jnz mainloop ;if byte[edi]=byte[esi] then goto match label, because a match byte was found...
!;match: ;here we have got inside a second treatment: We are in a possible total match, lets see if it is a complete match or it is a fake:
!mov ecx,edi ;save this position
!@@:
!cmp byte[edi],bl ;check if end of first string is reached
!jz fin ;if not reached then end
!cmp byte[esi],bl ;check if end of second string is reached
!jz @f ;if so, here was a complete match
!cmpsb ;compare one more byte
!jz @r ;if equal, lets see if the deceit continues, or rather it could be a real complete match.
!mov edi,ecx ;ohhh! it was a deceit! Restore this
!jmp mainloop ;What a patient! lets continue searching for another possible match and why not, a possible complete match...
!;complete match was found:
!@@:inc eax ;increment complete matches counter
!jmp mainloop ;lets search for another possible complete match!
!fin:
ProcedureReturn
EndProcedure
;Grrr!: Z-80 had conditional CALL, Ix86 doesn't !?
a$="ureruPururePe ruPurePurPuPure uresdfhg ureeurPeruPuruee sPuuredil hPPPrtur eurePuree urePurePuure"
MessageRequester("",Str(CountStrings(a$,"Pure")),0)
;Can use function input parameters as normal pointers:
;Procedure.l CountStrings(*a,*s)
;but then you have to call function using pointers too:
;CountStrings(@a$,@"Pure")
Code: Select all
a$="ureruPururePe ruPurePurPuPure uresdfhg ureeurPeruPuruee sPuuredil hPPPrtur eurePuree urePurePuure"
MessageRequester("",Str(CountStrings(a$,"PPr")),0)
Code: Select all
Procedure.l CountStrings(a.s,s.s)
!cld ;clear DF (Direction Flag)
!mov edi,dword[esp] ;load edi register with pointer to first string
!mov esi,dword[esp+4] ;load esi register with pointer to second string (the string to search)
!xor eax,eax ;set eax register to NULL
!mov bl,al ;set bl register to NULL
!mov edx,esi ;save this value in edx to avoid, as much as possible, to have to read data from memory in the main loop.
!;If any of two strings is empty then end program and matches found is 0:
!cmp byte[esi],bl ;test if second string is empty
!jz fin ;if so, then end
!;Main loop:
!mainloop:
!cmp byte[edi],bl ;check if end of first string is reached
!jz fin ;if not reached then end
!mov esi,edx ;restore this
!cmpsb ;what this instruction do is just compare byte[edi] with byte[esi] and increment edi and esi values by 1
!jnz mainloop ;if byte[edi]=byte[esi] then goto match label, because a match byte was found...
!;match: ;here we have got inside a second treatment: We are in a possible total match, lets see if it is a complete match or it is a fake:
!mov ecx,edi ;save this position
!@@:
!cmp byte[esi],bl ;check if end of second string is reached
!jz @f ;if so, here was a complete match
!cmpsb ;compare one more byte
!jz @r ;if equal, lets see if the deceit continues, or rather it could be a real complete match.
!mov edi,ecx ;ohhh! it was a deceit! Restore this
!jmp mainloop ;What a patient! lets continue searching for another possible match and why not, a possible complete match...
!;complete match was found:
!@@:inc eax ;increment complete matches counter
!jmp mainloop ;lets search for another possible complete match!
!fin:
ProcedureReturn
EndProcedure
;Grrr!: Z-80 had conditional CALL, Ix86 doesn't !?
a$="ureruPururePe ruPurePurPuPure uresdfhg ureeurPeruPuruee sPuuredil hPPPrtur eurePuree urePurePur"
b$="abcdeaaa"
c.s="Pur":PokeB(@c+3,0):PokeB(@c+4,Asc("e")):PokeB(@c+5,0)
d$="a"
MessageRequester("Should be 1",Str(CountStrings(PeekS(@c+4),"e")),0)
MessageRequester("Should be 1",Str(CountStrings(c,"Pur")),0)
MessageRequester("Should be 0",Str(CountStrings(c,"Pure")),0)
MessageRequester("Should be 1",Str(CountStrings(a$,"PPr")),0)
MessageRequester("Should be 4",Str(CountStrings(b$,"a")),0)
MessageRequester("Should be 1",Str(CountStrings(d$,"a")),0)
MessageRequester("Should be 0",Str(CountStrings(d$,"aa")),0)
MessageRequester("Should be 1",Str(CountStrings(b$,"aa")),0)
MessageRequester("Should be 4",Str(CountStrings(a$,"Pure")),0)
;Can use function input parameters as normal pointers:
;Procedure.l CountStrings(*a,*s)
;but then you have to call function using pointers too:
;CountStrings(@a$,@"Pure")
Code: Select all
Procedure.i EncontrarSecuenciaenCadena(*cadena.byte,*secuencia.byte,lc.i,ls.i,List e.i())
;Cuenta las veces que una cadena dada de bytes se repite dentro de otra cadena dada de bytes
; '*cadena.byte' es la cadena principal de bytes
; '*secuencia.byte' es la secuencia a buscar
; 'lc.i' es la longitud de la cadena principal
; 'ls.i' es la longitud de la secuencia a buscar
; 'List e.i()' es la lista para rellenar de en qué posiciones, dentro de '*cadena.byte', están las coincidencias encontradas
; Devuelve el número de coincidencias
Protected *cadena0.byte=*cadena,*secuencia0.byte=*secuencia,n.i=ListSize(e())
While *cadena-*cadena0<=lc
While *cadena\b=*secuencia\b
*secuencia+1:*cadena+1
If *secuencia-*secuencia0=ls:AddElement(e()):e()=*cadena-*cadena0-ls
ElseIf *cadena-*cadena0=lc:Break 2; => existe secuencia truncada al final de la cadena, concretamente en 'lc-(*secuencia-*secuencia0)'
Endif
Wend
*secuencia=*secuencia0
*cadena+1
Wend
ProcedureReturn ListSize(e())-n
EndProcedure