Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strlen in assembly

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

like image 799
Michel Avatar asked Feb 18 '11 12:02

Michel


4 Answers

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.

like image 127
Jester Avatar answered Nov 18 '22 06:11

Jester


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
like image 33
Michel Avatar answered Nov 18 '22 06:11

Michel


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.

like image 27
unwind Avatar answered Nov 18 '22 06:11

unwind


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
like image 40
Zimbabao Avatar answered Nov 18 '22 08:11

Zimbabao