strlen in assembly

21,652

Solution 1

You are not accessing bytes (characters), but doublewords. So your code is not looking for a single terminating zero, it is looking for 4 consecutive zeroes. Note that won't always return correct value +4, it depends on what the memory after your string contains.

To fix, you should use byte accesses, for example by changing edx to dl.

Solution 2

Thanks for your answers. Under here working code for anyone who has the same problem as me.

section .text
    [GLOBAL stringlen:]

stringlen:  
    push ebp
    mov ebp, esp

    mov edx, [ebp+8]    ; the string
    xor eax, eax        ; loop counter

    jmp if

then:
    inc eax

if:
    mov cl, [edx+eax]
    cmp cl, 0x0
    jne then

end:
    pop ebp
    ret

Solution 3

Not sure about the four, but it seems obvious it will always return the proper length + 1, since eax is always increased, even if the first byte read from the string is zero.

Solution 4

Change the line

mov edx, [ecx+eax]

to

mov dl, byte [ecx+eax]

and

  cmp edx, 0x0 ; null byte

to

  cmp dl, 0x0 ; null byte

Because you have to compare only byte at a time. Following is the code. Your original code got off-by-one error. For "h" it will return two h + null character.

section .text
    [GLOBAL stringlen:] ; C function

stringlen:
    push ebp
    mov ebp, esp        ; setup the stack frame

    mov ecx, [ebp+8]

    xor eax, eax        ; loop counter


startLoop:
    xor dx, dx
    mov dl, byte [ecx+eax]
    inc eax

    cmp dl, 0x0 ; null byte
    jne startLoop
end:
    pop ebp

    ret
Share:
21,652
Admin
Author by

Admin

Updated on February 19, 2020

Comments

  • Admin
    Admin about 4 years

    I made my own implementation of strlen in assembly, but it doesn't return the correct value. It returns the string length + 4. Consequently. I don't see why.. and I hope any of you do...

    Assembly source:

    section .text
        [GLOBAL stringlen:] ; C function
    
    stringlen:  
        push ebp
        mov ebp, esp        ; setup the stack frame
    
        mov ecx, [ebp+8]
    
        xor eax, eax        ; loop counter
    
    
    startLoop:
        xor edx, edx
        mov edx, [ecx+eax]
        inc eax
    
        cmp edx, 0x0 ; null byte    
        jne startLoop
    end:    
        pop ebp
    
        ret
    

    And the main routine:

    #include <stdio.h>
    
    extern int stringlen(char *);
    
    int main(void)
    {
      printf("%d", stringlen("h"));
    
      return 0;
    }
    

    Thanks