I just made a working implementation of calculating a string's length, but I'm not exactly sure it's the most efficient way. I divide the string up in blocks of four bytes each (32 bits), and add 4 to EAX. Once I hit a completely NULL block, I roll back the count of EAX by 4 bytes, and then calculate the final block's size one byte at a time. It only works using ASCII characters, and is limited to 32 bit computing (though that can be easily upgraded to 64 bit soon). I'm using assembly on a Linux maching using NASM. Here's the code:
; Function to compute the length of a string in blocks
; this only works in ASCII, or else it may give the wrong character count.
; input register: EAX - the string
section .data
BYTE_COUNT equ 4 ;4 bytes = 32 bits
NULL_TERMINATOR equ 0 ;\0, aka 0
section .text
global _strlen ;main entry point
_strlen:
push ebp ; c calling convention: preserve ebp
mov ebx, eax ; mov to ebx the string
jmp _NextBlock ; go to _NextChar
_NextBlock:
cmp word [eax], NULL_TERMINATOR ; Compare whether or not this block is completely null (e.g. 0)
jz _RollbackFinalBlock ; if it is, jump to _RollbackFinalBlock
; if not...
add eax, BYTE_COUNT ; Add to EAX the block size
jmp _NextBlock; repeat loop
_RollbackFinalBlock:
sub eax, BYTE_COUNT ;Subtract the block size from EAX, because it is null
jmp _FinalizeFinalBlock ; go to _FinalizeFinalBlock
_FinalizeFinalBlock:
cmp byte[eax], NULL_TERMINATOR ;Compare the characters of the final block to the null byte.
jz _Exit ;if this byte is null, proceed to _Exit
; if not...
inc eax ;increment EAX
jmp _FinalizeFinalBlock ;repeat loop
_Exit:
dec eax ; We will have a null terminator at the end. remove it.
sub eax, ebx ; compute difference to get answer, and store result in EAX
pop ebp ; load preserved EBP value from the stack
ret ; exit this function
You can test this function by linking it with a c program, and calling it from there.
The problem I have is that I have an extra jump to _RollbackFinalBlock and _FinalizeFinalBlock. Is there a way to make this implementation faster and more efficient?
ebp
but then usesesp
to access stack parameters. Second, you can altereax
,edx
andecx
but assuming the usual System V ABI, all other register contents should be preserved. – Edward Apr 25 at 13:38