Board.KolibriOS.org

Official KolibriOS board
It is currently Sun Aug 18, 2019 12:51 pm

All times are UTC+03:00




Post new topic  Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Sun Dec 01, 2013 12:51 pm 
Offline

Joined: Thu Feb 19, 2009 12:57 pm
Posts: 68
EDIT by yogev_ezra: Выделил "Реализация strlen на ассемблере" в отдельную тему.

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


Top
   
PostPosted: Sun Dec 01, 2013 1:06 pm 
Offline
User avatar

Joined: Fri Jan 27, 2006 3:06 pm
Posts: 1071
Insolor wrote:
Искал реализацию strlen на ассемблере, наткнулся на этот сайт:
http://www.int80h.org/ - Unix Assembly Language Programming
В примерах используется intel синтаксис.

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


Top
   
PostPosted: Sun Dec 01, 2013 4:30 pm 
Offline

Joined: Thu Feb 19, 2009 12:57 pm
Posts: 68
Heavyiron wrote:
Insolor wrote:
Искал реализацию strlen на ассемблере, наткнулся на этот сайт:
http://www.int80h.org/ - Unix Assembly Language Programming
В примерах используется intel синтаксис.

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

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


Top
   
PostPosted: Sun Dec 01, 2013 4:33 pm 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
Heavyiron wrote:
http://www.manhunter.ru/assembler/403_n ... blere.html - там 3 варианта strlen в зависимости от того, что требуется производительность или малый размер кода.

Во втором варианте можно дальше пойти:
Spoiler: Show
Code:
cmp     byte [eax+3], 0
; ..............................
cmp     byte [eax+255], 0

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

Первый вариант — наверное, первое, что приходит в голову :)
Я примерно так же сделал в kernel32, которая используется в PELoad.
lstrlenA, lstrlenW:
Spoiler: Show
Code:
;**********************************************************************************
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.
У меня:
Spoiler: Show
Code:
;**********************************************************************************
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:
Spoiler: Show
Code:
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, может быть, там уже что-то изменилось.


Top
   
PostPosted: Sun Dec 01, 2013 5:02 pm 
Offline
User avatar

Joined: Fri Jan 27, 2006 3:06 pm
Posts: 1071
Я у mike.dld в тинипаде наткнулся на 3-й вариант и он оказался на 4 байта короче и совсем чуть-чуть быстрее, чем первый:
Code:
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
На нем и остановился для своих целей.


Top
   
PostPosted: Sun Dec 01, 2013 5:34 pm 
Offline

Joined: Sun Oct 30, 2011 6:43 pm
Posts: 1499
Heavyiron, ещё 3 подобных варианта:
Spoiler: Show
Code:
; ------------------------------------
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
; ------------------------------------


Top
   
PostPosted: Sun Dec 01, 2013 5:58 pm 
Offline
User avatar

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


Top
   
PostPosted: Thu Apr 10, 2014 8:46 pm 
Offline
Public Relations
User avatar

Joined: Mon Jun 07, 2010 12:01 pm
Posts: 1879
Выделил "Реализация strlen на ассемблере" в отдельную тему.

Ещё 1 вариант от 0CodErr:
Code:
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


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 8 posts ] 

All times are UTC+03:00


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Limited