Linux 在装配中挣扎

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5041481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:54:30  来源:igfitidea点击:

strlen in assembly

linuxassemblyx86nasmstrlen

提问by Michel

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:

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

And the main routine:

和主要例程:

#include <stdio.h>

extern int stringlen(char *);

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

  return 0;
}

Thanks

谢谢

采纳答案by Jester

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.

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

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

要修复,您应该使用字节访问,例如通过更改edxdl.

回答by unwind

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

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

回答by Satya

I think your inc should be after the jne. I'm not familiar with this assembly, so I don't really know.

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

回答by Zimbabao

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.

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

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

回答by Michel

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

回答by sharow

More easy way here(ASCII zero terminated string only):

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

REPE SCAS m8

RPE SCAS m8

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

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