Board.KolibriOS.org

Официальный форум KolibriOS
Текущее время: Пт май 26, 2017 11:50 pm

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 8 сообщений ] 
Автор Сообщение
 Заголовок сообщения: Реализация strlen на ассемблере
СообщениеДобавлено: Вс дек 01, 2013 12:51 pm 
Не в сети

Зарегистрирован: Чт фев 19, 2009 12:57 pm
Сообщения: 69
EDIT by yogev_ezra: Выделил "Реализация strlen на ассемблере" в отдельную тему.

Искал реализацию strlen на ассемблере, наткнулся на этот сайт:
http://www.int80h.org/ - Unix Assembly Language Programming
В примерах используется intel синтаксис.


Вернуться к началу
 Заголовок сообщения: Re: Ссылки на сайты
СообщениеДобавлено: Вс дек 01, 2013 1:06 pm 
Не в сети
Аватара пользователя

Зарегистрирован: Пт янв 27, 2006 3:06 pm
Сообщения: 1070
Insolor писал(а):
Искал реализацию strlen на ассемблере, наткнулся на этот сайт:
http://www.int80h.org/ - Unix Assembly Language Programming
В примерах используется intel синтаксис.

http://www.manhunter.ru/assembler/403_n ... blere.html - там 3 варианта strlen в зависимости от того, что требуется производительность или малый размер кода.


Вернуться к началу
 Заголовок сообщения: Re: Ссылки на сайты
СообщениеДобавлено: Вс дек 01, 2013 4:30 pm 
Не в сети

Зарегистрирован: Чт фев 19, 2009 12:57 pm
Сообщения: 69
Heavyiron писал(а):
Insolor писал(а):
Искал реализацию strlen на ассемблере, наткнулся на этот сайт:
http://www.int80h.org/ - Unix Assembly Language Programming
В примерах используется intel синтаксис.

http://www.manhunter.ru/assembler/403_n ... blere.html - там 3 варианта strlen в зависимости от того, что требуется производительность или малый размер кода.

Эту статью вроде просматривал, но уже забыл про нее, поэтому полез в поиск. Для моих целей достаточно будет и первого варианта.


Вернуться к началу
 Заголовок сообщения: Re: Ссылки на сайты
СообщениеДобавлено: Вс дек 01, 2013 4:33 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 911
Heavyiron писал(а):
http://www.manhunter.ru/assembler/403_n ... blere.html - там 3 варианта strlen в зависимости от того, что требуется производительность или малый размер кода.

Во втором варианте можно дальше пойти:
Спойлер: Показать
Код:
cmp     byte [eax+3], 0
; ..............................
cmp     byte [eax+255], 0

Если точно известно, сколько памяти выделено под строку(например, выделено 4K), то можно смело читать dword за один раз. Примерно так делается, например, в libxds, которая идёт вместе с XDS Modula-2/Oberon-2 compiler.

Первый вариант — наверное, первое, что приходит в голову :)
Я примерно так же сделал в kernel32, которая используется в PELoad.
lstrlenA, lstrlenW:
Спойлер: Показать
Код:
;**********************************************************************************
lstrlenA: ;////////////////////////////////////////////////////////////////////////
;**********************************************************************************
%define lpString              [esp +  4 +1*4] ; null-terminated string to be checked
        push   edi

        mov    edi, lpString
        xor    ecx, ecx
        dec    ecx
        xor    al, al
        repne scasb
        not    ecx
        dec    ecx
        mov    eax, ecx

        pop    edi
        ret    4
%undef lpString
align 16
;**********************************************************************************
lstrlenW: ;////////////////////////////////////////////////////////////////////////
;**********************************************************************************
%define lpString              [esp +  4 +1*4] ; null-terminated string to be checked
        push   edi

        mov    edi, lpString
        xor    ecx, ecx
        dec    ecx
        xor    ax, ax
        repne scasw
        not    ecx
        dec    ecx
        mov    eax, ecx

        pop    edi
        ret    4
%undef lpString

Я удивился, когда потом обнаружил почти то же самое в исходниках HX DOS Extender.
Но там не всё так хорошо, как могло быть.
Например lstrcatA.
У меня:
Спойлер: Показать
Код:
;**********************************************************************************
lstrcatA: ;////////////////////////////////////////////////////////////////////////
;**********************************************************************************
%define lpString1             [esp +  4 +2*4] ; first null-terminated string
%define lpString2             [esp +  8 +2*4] ; null-terminated string to be added
        push   esi
        push   edi

        mov    esi, lpString2
        xor    ecx, ecx
        xor    eax, eax
        mov    edi, esi
        dec    ecx
        repne scasb
        mov    edx, ecx
        mov    edi, lpString1
        repne scasb
        dec    edi
        not    edx
        mov    eax, lpString1
        mov    ecx, edx
        shr    ecx, 2
        rep movsd
        mov    ecx, edx
        and    ecx, 3
        rep movsb

        pop    edi
        pop    esi
        ret    8
%undef lpString1
%undef lpString2
У Japheth:
Спойлер: Показать
Код:
lstrcatA proc uses esi edi string1:ptr byte,string2:ptr byte

       xor     eax,eax
       mov     ecx,-1
       mov     edi,string2
       repne   scasb
       push    ecx
       mov     edi,string1
       repne   scasb
       dec     edi
       pop     ecx
       not     ecx
       mov     esi,string2
       shr     ecx,1
       rep     movsw
       adc     ecx,ecx
       rep     movsb
       mov     eax,string1
       ret
lstrcatA endp
Первый вариант с rep movsd, конечно будет быстрее, чем второй с rep movsw. Я привёл часть исходника из v2.16, stable. Сейчас также доступна v2.17, release candidate, может быть, там уже что-то изменилось.


Вернуться к началу
 Заголовок сообщения: Re: Ссылки на сайты
СообщениеДобавлено: Вс дек 01, 2013 5:02 pm 
Не в сети
Аватара пользователя

Зарегистрирован: Пт янв 27, 2006 3:06 pm
Сообщения: 1070
Я у mike.dld в тинипаде наткнулся на 3-й вариант и он оказался на 4 байта короче и совсем чуть-чуть быстрее, чем первый:
Код:
proc _lstrlen lpStr:DWORD
        push    ebx
        mov     ebx,[lpStr]
        xor     eax,eax
    @@: cmp     byte[ebx+eax],0
        je      @f
        inc     eax
        jmp     @b
    @@: pop     ebx
        ret
endp
На нем и остановился для своих целей.


Вернуться к началу
 Заголовок сообщения: Re: Ссылки на сайты
СообщениеДобавлено: Вс дек 01, 2013 5:34 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 911
Heavyiron, ещё 3 подобных варианта:
Спойлер: Показать
Код:
; ------------------------------------
strlen1:
        mov     ecx, [lpStr]
        mov     eax, ecx
.next:       
        cmp     [eax], byte 0
        je      .exit
        inc     eax
        jmp     .next
.exit:       
        sub     eax, ecx
        ret     4
; ------------------------------------
strlen2:
        mov     eax, [lpStr]
.next:       
        cmp     [eax], byte 0
        je      .exit
        inc     eax
        jmp     .next
.exit:       
        sub     eax, [lpStr]
        ret     4
; ------------------------------------
strlen3:
        mov     eax, [lpStr]
        dec     eax
.next: 
        inc     eax
        cmp     [eax], byte 0
        jne     .next
        sub     eax, [lpStr]
        ret     4
; ------------------------------------


Вернуться к началу
 Заголовок сообщения: Re: Ссылки на сайты
СообщениеДобавлено: Вс дек 01, 2013 5:58 pm 
Не в сети
Аватара пользователя

Зарегистрирован: Пт янв 27, 2006 3:06 pm
Сообщения: 1070
Последний крут (позволяет избавиться от push/pop, потому чуть быстрее и по размеру еще на 3 байта короче). А если заведомо известно, что длина строки ненулевая, можно убрать dec eax - еще минус 1 байт.
Код:
proc _lstrlen lpStr:DWORD
        mov     eax, [lpStr]
@@: 
        inc     eax
        cmp     byte [eax], 0
        jne     @b
        sub     eax, [lpStr]
        ret
endp
Красота!


Вернуться к началу
 Заголовок сообщения: Re: Реализация strlen на ассемблере
СообщениеДобавлено: Чт апр 10, 2014 8:46 pm 
Не в сети
Public Relations
Аватара пользователя

Зарегистрирован: Пн июн 07, 2010 12:01 pm
Сообщения: 1879
Выделил "Реализация strlen на ассемблере" в отдельную тему.

Ещё 1 вариант от 0CodErr:
Код:
strlen:
        mov     eax, [src]
.next:
        cmp    [eax], byte 1 ; IF byte[eax] = 0 THEN carry = 1
        inc    eax           ; after "inc" carry not affected
        jnc    .next         ; IF carry = 0 THEN next
        sbb    eax, [src]    ; eax = eax - [src] - carry ; we here IF carry = 1


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 8 сообщений ] 

Часовой пояс: UTC+03:00


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB