6

我在汇编中自己实现了 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;
}

谢谢

4

6 回答 6

4

感谢您的回答。在此处为与我有相同问题的任何人提供工作代码。

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
于 2011-02-18T14:26:56.070 回答
4

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

要解决此问题,您应该使用字节访问,例如更改edxdl.

于 2011-02-18T13:24:15.983 回答
1

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

于 2011-02-18T12:55:19.633 回答
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
于 2011-02-18T13:25:55.730 回答
0

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

重复 SCAS m8

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

于 2011-02-18T21:12:40.813 回答
-2

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

于 2011-02-18T12:55:30.447 回答