Code: Select all
CompilerIf #PB_Compiler_Processor = 4
Macro eax : rax : EndMacro
Macro ebx : rbx : EndMacro
Macro ecx : rcx : EndMacro
Macro edx : rdx : EndMacro
Macro esi : rsi : EndMacro
Macro edi : rdi : EndMacro
Macro ebp : rbp : EndMacro
Macro esp : rsp : EndMacro
Macro dword : qword :EndMacro
Macro octets : 8 :EndMacro
Debug "x64 mode"
CompilerElse
Macro octets : 4 :EndMacro
Debug "x86 mode"
CompilerEndIf
Procedure.l GetPosOfLastChar(*searchThisString, *CharToFind)
CompilerIf #PB_Compiler_Processor = 4 ; If compiler is in x64 mode
!push rsi ;preserve registers
!push rdi
!mov rsi, [p.p_searchThisString+16] ;Get address of string in rsi-add 16 to the address of the string, ie 8 for each push instruction
!mov rdi, [p.p_CharToFind+16]
!mov rdx, rsi
CompilerElse
!push esi ;preserve registers
!push edi
!mov esi, [p.p_searchThisString+8] ;Get address of string in esi-add 8 to the address of the string, ie 4 for each push instruction
!mov edi, [p.p_CharToFind+8]
!mov edx, esi
CompilerEndIf
!or ecx, $ffffffff ;Set counter to -1
!cld ;makes esi count upwards when lodsw is used (hence fetches next character in string)
!l_CountChars:
!inc ecx ; increment counter (on first run this makes ecx = 0)
!lodsw ; get word pointed to by esi in ax then inc esi - use word for unicode strings [lodsb for ascii strings]
!test al,al ; check if low byte is zero ie the string terminator
!jnz l_CountChars ; get next character in string
!mov eax, ecx ; copy count of characters into eax
!mov esi, edx ; restore esi - (lodsw has changed its value)
!dec ecx ; decrease count of characters by 1
!shl ecx, 1 ; multiply count of characters by 2
!add esi, ecx ; esi now points to last char in string
!std ; makes esi count downwards when lodsw is used (hence fetches previous character in string)
!mov ecx, eax ; copy count of characters to ecx
!l_CheckNextChar:
!lodsw ; get word pointed to by esi in ax then dec esi- use word for unicode strings [lodsb for ascii strings]
!dec ecx ; decrease counter
!cmp ecx, -1
!jz l_NotFound ;If counter is -1 then character has not been found, so return a not found value of 0
!cmp ax, [edi]
!jne l_CheckNextChar
!mov ax, cx
!inc ax ;Ensures position of character found starts at 1
!jmp l_exit
!l_NotFound:
!mov eax, 0
!l_exit:
CompilerIf #PB_Compiler_Processor = 4 ; If compiler is in x64 mode
!pop rdi
!pop rsi ;preserve the rsi register
CompilerElse
!pop edi
!pop esi ;preserve the esi register
CompilerEndIf
ProcedureReturn ;return eax
EndProcedure
CharToFind$ = "\"
a$ = "1234567890123456789\D\"
Debug GetPosOfLastChar(@a$, @CharToFind$)
a$ = "123456789012345C\"
Debug GetPosOfLastChar(@a$, @CharToFind$)
a$ = "\123456789"
Debug GetPosOfLastChar(@a$, @CharToFind$)
a$ = "123456789ABC"
Debug GetPosOfLastChar(@a$, @CharToFind$)