strlen in assembly

时间:2011-02-18 12:51:51

标签: linux assembly x86 nasm strlen

我在程序集中自己实现了strlen,但它没有返回正确的值。它返回字符串长度+4。因此。我不明白为什么......我希望你们中的任何一个......

装配来源:

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

主要程序:

#include <stdio.h>

extern int stringlen(char *);

int main(void)
{
  printf("%d", stringlen("h"));

  return 0;
}

感谢

6 个答案:

答案 0 :(得分:3)

您不是访问字节(字符),而是双字。因此,您的代码不会寻找单个终止零,它正在寻找4个连续的零。请注意,并不总是返回正确的值+4,它取决于字符串包含的内存。

要修复,您应该使用字节访问,例如将edx更改为dl

答案 1 :(得分:3)

感谢您的回答。在这里为任何与我有同样问题的人编写代码。

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

答案 2 :(得分:1)

不确定这四个,但很明显它总会返回正确的长度+ 1,因为eax 总是增加,即使从字符串读取的第一个字节是零。

答案 3 :(得分:1)

更改行

mov edx, [ecx+eax]

mov dl, byte [ecx+eax]

  cmp edx, 0x0 ; null byte

  cmp dl, 0x0 ; null byte

因为你必须一次只比较一个字节。 以下是代码。您的原始代码出现了一个错误。对于“h”,它将返回两个h + null字符。

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

答案 4 :(得分:-1)

这里更简单的方法(仅限ASCII零终止字符串):

REPE SCAS m8

http://pdos.csail.mit.edu/6.828/2006/readings/i386/REP.htm

答案 5 :(得分:-2)

我认为你的公司应该在jne之后。我不熟悉这个集会,所以我真的不知道。