3
\$\begingroup\$

This is a simple strlen function with registers documented:

;in rdi - string to measure
;out rax - len
.my_strlen:
test rdi, rdi
jz ptr_error
or rcx, 0xFFFFFFFFFFFFFFFF
mov al, 0
cld
repne scasb
mov rax, 0xFFFFFFFFFFFFFFFF
sub rax, rcx
ret

NOTE: This code assumes a "C-Style string"; that is, a NUL-terminated string.

\$\endgroup\$
2
\$\begingroup\$
or rcx, 0xFFFFFFFFFFFFFFFF

This is an optimization for size, but it does not break the dependency on the old value of rcx (at least not yet, maybe someday, it's not an impossible feature). That's a minor point compared to overall cost of a strlen but it's something to know so you can make the choice deliberately.

cld

Should be redundant, typical calling conventions specify that the direction flag is cleared at function call boundaries so your strlen shouldn't be called with it set to backwards.

mov rax, 0xFFFFFFFFFFFFFFFF
sub rax, rcx

mov-ing a 64bit immediate is surprisingly slow, and also a huge instruction. An alternative is:

not rcx
mov rax, rcx
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.