Code: Alles auswählen
! macro EndMacro {}
; Assembler macro to align code on a given boundary,
; aligning loop starts on 8 byte boundaries can speed up the code
; by about 1.5 to 2 times!
! macro calignjmp value
! {
! local dest
!
! if ((value - 1) - ((($ - $$) + value - 1) mod value)) > 3
! makeDest equ 1
! jmp dest
! else
! makeDest equ 0
! end if
!
! rept value
! \{
! if ($ - $$) mod value
! nop
! end if
! \}
! dest:
! } EndMacro
; Uncommend the next 3 lines, if you want to replace
; Mid with FMid in all places:
; Macro Mid(string, start, length)
; FMid2(@string,start,length)
; EndMacro
CompilerIf #PB_Compiler_Unicode
Procedure.s FMid2(*srcPtr.Byte, start.l, length.l)
!MOV edx,[p.p_srcPtr]
!MOV ecx,[p.v_length]
!TEST edx,edx
!JZ ll_fmid2_empty
!TEST ecx,ecx
!JLE ll_fmid2_empty
!MOV ecx,[p.v_start]
!CMP ecx,1
!JLE ll_fmid2_fmid2return
!XOR eax,eax
!DEC ecx
!calignjmp 4
scan1:
!SUB ecx,8
!JL ll_fmid2_scanend1
!CMP [edx],ax
!JE ll_fmid2_scanend2
!ADD edx,2
!CMP [edx],ax
!JE ll_fmid2_scanend2
!ADD edx,2
!CMP [edx],ax
!JE ll_fmid2_scanend2
!ADD edx,2
!CMP [edx],ax
!JE ll_fmid2_scanend2
!ADD edx,2
!CMP [edx],ax
!JE ll_fmid2_scanend2
!ADD edx,2
!CMP [edx],ax
!JE ll_fmid2_scanend2
!ADD edx,2
!CMP [edx],ax
!JE ll_fmid2_scanend2
!ADD edx,2
!CMP [edx],ax
!JE ll_fmid2_scanend2
!ADD edx,2
!JMP ll_fmid2_scan1
scanend1:
!ADD ecx,8
!JZ ll_fmid2_scanend2
scan2:
!CMP [edx],ax
!JE ll_fmid2_scanend2
!ADD edx,2
!DEC ecx
!JNZ ll_fmid2_scan2
scanend2:
!MOV [p.p_srcPtr],edx
fmid2return:
ProcedureReturn PeekS(*srcPtr, length)
empty:
ProcedureReturn ""
EndProcedure
CompilerElse
Procedure.s FMid2(*srcPtr.Byte, start.l, length.l)
!MOV edx,[p.p_srcPtr]
!MOV ecx,[p.v_length]
!TEST edx,edx
!JZ ll_fmid2_empty
!TEST ecx,ecx
!JLE ll_fmid2_empty
!MOV ecx,[p.v_start]
!CMP ecx,1
!JLE ll_fmid2_fmid2return
!XOR eax,eax
!DEC ecx
!calignjmp 4
scan1:
!SUB ecx,8
!JL ll_fmid2_scanend1
!CMP [edx],al
!JE ll_fmid2_scanend2
!INC edx
!CMP [edx],al
!JE ll_fmid2_scanend2
!INC edx
!CMP [edx],al
!JE ll_fmid2_scanend2
!INC edx
!CMP [edx],al
!JE ll_fmid2_scanend2
!INC edx
!CMP [edx],al
!JE ll_fmid2_scanend2
!INC edx
!CMP [edx],al
!JE ll_fmid2_scanend2
!INC edx
!CMP [edx],al
!JE ll_fmid2_scanend2
!INC edx
!CMP [edx],al
!JE ll_fmid2_scanend2
!INC edx
!JMP ll_fmid2_scan1
scanend1:
!ADD ecx,8
!JZ ll_fmid2_scanend2
scan2:
!CMP [edx],al
!JE ll_fmid2_scanend2
!INC edx
!DEC ecx
!JNZ ll_fmid2_scan2
scanend2:
!MOV [p.p_srcPtr],edx
fmid2return:
ProcedureReturn PeekS(*srcPtr, length)
fmid2_empty:
ProcedureReturn ""
EndProcedure
CompilerEndIf
OpenConsole()
Global tStart.l, tStart2.l, tDiff.d
Global str1.s, str1Pos.l, str1Len.l = 4096, str1Mid.s, str1FMid.s
Global i.l, iEnd.l, strCh.l
Global start.l, length.l
strCh = 1
For i = 1 To str1Len
str1 + Chr(strCh)
strCh + 1
If strCh > 255: strCh = 1: EndIf
Next i
iEnd = 10000
For i = 1 To iEnd
start = Random(10000)-5000
length = Random(10000)-5000
str1Mid = Mid(str1, start, length)
str1FMid = FMid2(@str1, start, length)
If str1Mid <> str1FMid
PrintN("Error FMid: " + Str(start) + ", " + Str(length))
CallDebugger
EndIf
Next i
iEnd = 10000
For i = 1 To iEnd
start = Random(10000)-5000
length = Random(10000)-5000
str1Mid = Mid(str1, start, length)
str1FMid = FMid2(@str1, start, length)
If str1Mid <> str1FMid
PrintN("Error FMid2: " + Str(start) + ", " + Str(length))
CallDebugger
EndIf
Next i
PrintN(#CRLF$ + "Done")
While Inkey() = "": Delay(100): Wend