Yes you are right, it exits that code on a zero but drops directly into the following loop code. I am guilty of writing suicide code as I would not pass a zero length string to it but its easy enough to modify so it just exits the proc on a zero. When I get time I will set up a test piece and modify the algo. Thanks for finding it.
Slightly later : I think this one does the job, the old code did not crash but it did not tell you anything either. The test rdx, rdx caught the zero. I will put it back into a module shortly.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include64\masm64rt.inc
.data
test1 db " 1234567890",0
test2 db 0
ptst1 dq test1
ptst2 dq test2
.code
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
entry_point proc
rcall szLtrimx, ptst1, ptst1
conout ptst1,lf,lf
rcall szLtrimx, ptst2, ptst2
cmp rax, 0
jne @F
conout "String of 0 length passed",lf,lf
@@:
waitkey
invoke ExitProcess,0
ret
entry_point endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
NOSTACKFRAME
szLtrimx proc
; rcx = src string
; rdx = dest buffer
mov rax, rdx ; store buffer adress in RAX
sub rcx, 1
lbl0: ; trim the front chars off src
add rcx, 1
cmp BYTE PTR [rcx],0
jne @F
xor rax, rax
ret
@@:
cmp BYTE PTR [rcx], 33 ; ditch anything below ASCII 33
jb lbl0
mov r9, -1
lbl1:
REPEAT 3 ; unroll by 4
add r9, 1
movzx rdx, BYTE PTR [rcx+r9]
mov BYTE PTR [rax+r9], dl
test rdx, rdx
jz lbl2
ENDM
add r9, 1
movzx rdx, BYTE PTR [rcx+r9]
mov BYTE PTR [rax+r9], dl
test rdx, rdx
jnz lbl1
lbl2: ; return value is in RAX
ret
szLtrimx endp
STACKFRAME
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end