стрлен в сборе - PullRequest
       32

стрлен в сборе

4 голосов
/ 18 февраля 2011

Я сделал собственную реализацию 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 ]

3 голосов
/ 18 февраля 2011

Спасибо за ваши ответы.Ниже приведен рабочий код для тех, у кого такая же проблема, как у меня.

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
3 голосов
/ 18 февраля 2011

Вы обращаетесь не к байтам (символам), а к двойным словам.Таким образом, ваш код не ищет один завершающий ноль, он ищет 4 последовательных нуля.Обратите внимание, что не всегда будет возвращаться правильное значение +4, это зависит от того, какой объем памяти содержится в вашей строке.

Чтобы исправить, вы должны использовать байтовый доступ, например, изменив edx на dl.

1 голос
/ 18 февраля 2011

Измените строку

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
1 голос
/ 18 февраля 2011

Не уверен насчет четырех, но кажется очевидным, что он всегда вернет правильную длину + 1, поскольку eax равно всегда увеличено, даже если первый байт, прочитанный из строки, равен нулю. 1004 *

0 голосов
/ 19 февраля 2011

Более простой способ (только строка с нулевым окончанием ASCII):

REPE SCAS m8

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

0 голосов
/ 18 февраля 2011

Я думаю, что ваш inc должен быть после jne.Я не знаком с этой сборкой, поэтому не знаю.

...