Iczer Posted December 24, 2016 Posted December 24, 2016 Maybe someone have fast unicode-friendly string replacing function written in Assembler for work with UTF-8 encoded text in 32/64 bit scripts (FreeBasic) I'm ported this function to x64 by replacing exx registers names to rxx, but it work only fo ascii letters - UTF8 wont work. And currently i do not want resort to UTF-16... expandcollapse popup#ifdef __FB_64BIT__ Function StringReplaceASCII(TiStr As String ,TiFind As String ,TiRep As String ) As String '/' this function only 64bit Dim As ZString Ptr iStr,iFind, iRep Dim As Integer icor= 0 Dim As Integer i, code If TiStr="" Or TiFind="" Then Function = TiStr Exit Function EndIf If TiRep="" Then TiRep="?" icor=1 EndIf iStr=StrPtr(TiStr) iFind= StrPtr(TiFind) iRep= StrPtr(TiRep) Dim As Integer iSize=Len(TiStr)-Len(TiFind) Dim As ZString Ptr dStr=CAllocate(Len(TiStr)*20) Dim As String s Asm mov rsi,[iStr] add [iSize],rsi mov rbx,[iFind] inc dword Ptr[iSize] mov rdi,[dStr] End Asm Asm Sub rsi,1 Asm jmp Start1 Start2: add rsi,rcx Start1: add rsi,1 cmp [iSize],rsi jle Done movzx rax,Byte Ptr[rsi] cmp al,[rbx] je Match mov [rdi],al add rdi,1 jmp Start1 Match: mov rcx,-1 mov rdx,rbx B1: add rcx,1 movzx rax,Byte Ptr[rdx] Test rax,rax jz Change add rdx,1 cmp [rsi+rcx],al je B1 movzx rax,Byte Ptr[rsi] mov [rdi],al add rdi,1 jmp Start1 Change: mov rdx,[iRep] End Asm saute: Asm Sub rcx,1 Asm B2: movzx rax,Byte Ptr[rdx] Test rax,rax jz Start2 add rdx,1 mov [rdi],al add rdi,1 jmp B2 Done: mov rcx,-1 B3: add rcx,1 movzx rax,Byte Ptr[rsi+rcx] mov [rdi+rcx],al Test rax,rax jnz B3 ' mov rax,[dStr] ' mov [toto],rax End Asm s=*dStr If icor=0 Then Function = s Deallocate dStr Exit Function EndIf code=Asc("?") ' change it here if you want asm mov rsi, [dStr] mov rdx, -1 '' "get" pointer Xor rcx, rcx '' "put" pointer Test rsi, rsi '' in case passed null string jz 1f 0: inc rdx movzx rax, Byte Ptr [rsi+rdx] Test rax, rax jz 1f cmp rax,[code] ' je 0b mov [rsi+rcx], al inc rcx jmp 0b 1: mov [i], rcx End asm s=Left$(*dStr,i) Function = s Deallocate dStr End Function #Else Function StringReplaceASCII(TiStr As String ,TiFind As String ,TiRep As String ) As String '/' this function only 32bit Dim As ZString Ptr iStr,iFind, iRep Dim As Integer icor= 0 Dim As Integer i, code If TiStr="" Or TiFind="" Then Function = TiStr Exit Function EndIf If TiRep="" Then TiRep="?" icor=1 EndIf iStr=StrPtr(TiStr) iFind= StrPtr(TiFind) iRep= StrPtr(TiRep) Dim As Integer iSize=Len(TiStr)-Len(TiFind) Dim As ZString Ptr dStr=CAllocate(Len(TiStr)*20) Dim As String s Asm mov esi,[iStr] add [iSize],esi mov ebx,[iFind] inc dword Ptr[iSize] mov edi,[dStr] End Asm Asm Sub esi,1 Asm jmp Start1 Start2: add esi,ecx Start1: add esi,1 cmp [iSize],esi jle Done movzx eax,Byte Ptr[esi] cmp al,[ebx] je Match mov [edi],al add edi,1 jmp Start1 Match: mov ecx,-1 mov edx,ebx B1: add ecx,1 movzx eax,Byte Ptr[edx] Test eax,eax jz Change add edx,1 cmp [esi+ecx],al je B1 movzx eax,Byte Ptr[esi] mov [edi],al add edi,1 jmp Start1 Change: mov edx,[iRep] End Asm saute: Asm Sub ecx,1 Asm B2: movzx eax,Byte Ptr[edx] Test eax,eax jz Start2 add edx,1 mov [edi],al add edi,1 jmp B2 Done: mov ecx,-1 B3: add ecx,1 movzx eax,Byte Ptr[esi+ecx] mov [edi+ecx],al Test eax,eax jnz B3 ' mov eax,[dStr] ' mov [toto],eax End Asm s=*dStr If icor=0 Then Function = s Deallocate dStr Exit Function EndIf code=Asc("?") ' change it here if you want asm mov esi, [dStr] mov edx, -1 '' "get" pointer Xor ecx, ecx '' "put" pointer Test esi, esi '' in case passed null string jz 1f 0: inc edx movzx eax, Byte Ptr [esi+edx] Test eax, eax jz 1f cmp eax,[code] ' je 0b mov [esi+ecx], al inc ecx jmp 0b 1: mov [i], ecx End asm s=Left$(*dStr,i) Function = s Deallocate dStr End Function #EndIf or pretty same: expandcollapse popup#ifdef __FB_64BIT__ Function StringReplaceUnicode(iStr As ZString Ptr,iFind As ZString Ptr,iRep as ZString Ptr) As ZString Ptr Dim as integer iSize=Len(*iStr)-Len(*iFind) Asm mov rsi,[iStr] add [iSize],rsi mov rbx,[iFind] inc dword ptr[iSize] mov rdi,[dStr] sub rsi,1 jmp _Start1 _Start2: add rsi,rcx _Start1: add rsi,1 cmp [iSize],rsi jle _Done movzx rax,BYTE PTR[rsi] cmp al,[rbx] je _Match mov [rdi],al add rdi,1 jmp _Start1 _Match: mov rcx,-1 mov rdx,rbx _B1: add rcx,1 movzx rax,BYTE PTR[rdx] test rax,rax jz _Change add rdx,1 cmp [rsi+rcx],al je _B1 movzx rax,BYTE PTR[rsi] mov [rdi],al add rdi,1 jmp _Start1 _Change: mov rdx,[iRep] sub rcx,1 _B2: movzx rax,BYTE PTR[rdx] test rax,rax jz _Start2 add rdx,1 mov [rdi],al add rdi,1 jmp _B2 _Done: mov rcx,-1 _B3: add rcx,1 movzx rax,BYTE PTR[rsi+rcx] mov [rdi+rcx],al test rax,rax jnz _B3 mov rax,[dStr] mov [Function],rax End Asm End Function #Else Function StringReplaceUnicode(iStr As ZString Ptr,iFind As ZString Ptr,iRep as ZString Ptr) As ZString Ptr Dim as integer iSize=Len(*iStr)-Len(*iFind) Asm mov esi,[iStr] add [iSize],esi mov ebx,[iFind] inc dword ptr[iSize] mov edi,[dStr] sub esi,1 jmp _Start1 _Start2: add esi,ecx _Start1: add esi,1 cmp [iSize],esi jle _Done movzx eax,BYTE PTR[esi] cmp al,[ebx] je _Match mov [edi],al add edi,1 jmp _Start1 _Match: mov ecx,-1 mov edx,ebx _B1: add ecx,1 movzx eax,BYTE PTR[edx] test eax,eax jz _Change add edx,1 cmp [esi+ecx],al je _B1 movzx eax,BYTE PTR[esi] mov [edi],al add edi,1 jmp _Start1 _Change: mov edx,[iRep] sub ecx,1 _B2: movzx eax,BYTE PTR[edx] test eax,eax jz _Start2 add edx,1 mov [edi],al add edi,1 jmp _B2 _Done: mov ecx,-1 _B3: add ecx,1 movzx eax,BYTE PTR[esi+ecx] mov [edi+ecx],al test eax,eax jnz _B3 mov eax,[dStr] mov [Function],eax End Asm End Function #EndIf Also - speed wise - maybe just go with AutoItX.dll x86/x64 ?
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now