buf2buf

Тема в разделе "WASM.BEGINNERS", создана пользователем LEDVINA, 23 июн 2005.

  1. LEDVINA

    LEDVINA New Member

    Публикаций:
    0
    Регистрация:
    7 апр 2005
    Сообщения:
    22
    Адрес:
    Czech Republic
    Переписываю из буфера 1 в буфер 2... Пишу стандартно:



    mov ecx,length_to_copy

    mov edi,Buff2

    mov esi,Buff1

    rep movsb



    length_to_copy определяется динамически. Как правило, это килобайты. Есть мнение, что переписывая кусками побольше (MOVSD), будем быстрее. В А&О ничего не нашел... И что вообще предпочтительнее: movs m32,m32 или movsd?
     
  2. warsem

    warsem Сеня

    Публикаций:
    0
    Регистрация:
    26 янв 2005
    Сообщения:
    170
    Адрес:
    Германия, NRW
    Есть мнение, что переписывая кусками побольше (MOVSD), будем быстрее.

    ну а как же иначе. То цикл из n проходов, а то n/4. Конечно быстрей.
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    C movsd быстрее будет


    Код (Text):
    1.             mov     esi,offset Buff1
    2.             mov     edi,offset Buff2
    3.             mov     ecx,length_to_copy
    4.             shr     ecx,2
    5.             rep     movsd
    6.             mov     ecx,length_to_copy
    7.             and     ecx,3
    8.             rep     movsb
    9.  
    10.  




    Без movsd ещё быстрее будет




    Код (Text):
    1.             mov     esi,offset Buff1
    2.             mov     edi,offset Buff2
    3.             mov     ecx,length_to_copy
    4.             cmp     ecx,4
    5.             jl      b_c
    6.             sub     ecx,4
    7.          @@:  
    8.             mov     eax,[esi+ecx]
    9.             mov     [edi+ecx],eax
    10.             sub     ecx,4
    11.             js      @F
    12.             mov     eax,[esi+ecx]
    13.             mov     [edi+ecx],eax
    14.             sub     ecx,4
    15.             jns     @B
    16.          @@:
    17.             add     ecx,4
    18.         b_c:    
    19.             jz      _end
    20.          @@:
    21.             mov     al,[esi+ecx-1]
    22.             mov     [edi+ecx-1],al
    23.             dec     ecx
    24.             jnz     @B
    25.         _end:
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    LEDVINA

    > "В А&О ничего не нашел..."



    Видать плохо искал...

    Посмотри Копирование памяти, хотя там оптимизация под большие блоки. Но rep movsd для "килобайтных" блоков это наверное лучший вариант (имхо)
     
  5. LEDVINA

    LEDVINA New Member

    Публикаций:
    0
    Регистрация:
    7 апр 2005
    Сообщения:
    22
    Адрес:
    Czech Republic
    У, клево!! Спасибо!

    Э-э.. Осторожно спрашиваю: может лучше юзать CopyMemory? Ересь? Медленнее будет?
     
  6. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257


    Да.



    Да.
     
  7. LEDVINA

    LEDVINA New Member

    Публикаций:
    0
    Регистрация:
    7 апр 2005
    Сообщения:
    22
    Адрес:
    Czech Republic
    Хм.. В каких тогда случаях надо использовать CopyMemory?
     
  8. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Когда нужна не скорость, а маленький размер кода:

    push length_to_copy

    push B1

    push B2

    call RtlMoveMemory



    Это короче, чем циклы копирования
     
  9. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Что интересно, в MSDN RtlMoveMemory документирована только для DDK. kernel32.dll экспортирует эту ф-цию (на самом деле форвардит в ntdll.dll), но в хидерах эта ф-ция определена так:
    Код (Text):
    1. #define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
    Да оно и понятно - размер далеко не маленький, rep movsb будет на 4 байта меньше.
     
  10. LEDVINA

    LEDVINA New Member

    Публикаций:
    0
    Регистрация:
    7 апр 2005
    Сообщения:
    22
    Адрес:
    Czech Republic
    Мощно.. Кстати, почему Ртл? Обычный документированный MoveMemory вас уже не устраивает?
     
  11. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Ну всё-таки RtlMoveMemory (CopyMemory) это функция, без которой тяжело в языках, не имеющих возможности вставок ассемблерного кода. Для этих случаев это единственный приемлимый вариант. Тут уже не до размеров кода :)
     
  12. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Насколько я до сих пор знаю, RtlMoveMemory = CopyMemory.
     
  13. LEDVINA

    LEDVINA New Member

    Публикаций:
    0
    Регистрация:
    7 апр 2005
    Сообщения:
    22
    Адрес:
    Czech Republic
    Как интересно.. В WIN32 Programmer's Reference от Борланды светятся FillMemory, MoveMemory, ZeroMemory (как See also в CopyMemory) и никаких ртл-ов..
     
  14. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Борланд гонит :)

    Имхо, это всего лишь алиасы, например из басика :

    CopyMemory Lib "kernel32" Alias "RtlMoveMemory".

    Можно обозвать как угодно:

    ДвиньМоюМеморюОтсюдаТуда Lib "kernel32" Alias "RtlMoveMemory"

    и вызывать:

    Call ДвиньМоюМеморюОтсюдаТуда(Туда, Отсюда, Столько).

    И будет работать.



    Если посмотреть экспорт кернелл через Depends, то обнаруживается, что никаких там FillMemory, MoveMemory, ZeroMemory, CopyMemory нет.

    Есть RtlFillMemory, RtlMoveMemory, RtlZeroMemory.



    P.S.

    Сами они в кернелл не сидят, а импортируются кернелом из ntdll. Т.е. entry point обозначена как ntdll.RtlFillMemory, ntdll.RtlMoveMemory, ntdll.RtlZeroMemory
     
  15. LEDVINA

    LEDVINA New Member

    Публикаций:
    0
    Регистрация:
    7 апр 2005
    Сообщения:
    22
    Адрес:
    Czech Republic
    Познавательно..

    RADASM красит (выделяет цветом) и ртл-ы и НЕ-ртл-ы
     
  16. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Видимо он где-то считывает информацию, что это эквивалентные вещи
     
  17. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Да, есть только RTL. В хидерах вижуала они переопределяются на copymem, memset... или что-то в этом роде чтоб оптимизировать код по размеру и скорости. Не забывайте что само имя функции ("RtlCopyMemory" или как там её?) в IAT тоже место занимает. Зато эти ртл-функции тщательно проверяют валидность параметров, поэтому они "безопаснее" чем rep movsd.
     
  18. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Quantum

    Зато эти ртл-функции тщательно проверяют валидность параметров, поэтому они "безопаснее" чем rep movsd.

    В wxpsp2 ни ntdll.RtlMoveMemory, ни ntdll.RtlFillMemory, ни ntdll.RtlZeroMemory не проверяют валидность параметров. Единственное преимущество первой из них перед rep movsd, то, что она определяет и корректно справляется с возможным пересечением областей источника и приемника.
     
  19. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    "Документированной функции" MoveMemory не существует вообще. Определена она в заголовках так:
    Код (Text):
    1. #define MoveMemory(pbDst,pbSrc,cb)  memmove((pbDst),(pbSrc),(cb))
    2. #define MoveMemory RtlMoveMemory
    CopyMemory - это совершенно другая вещь:
     
  20. LEDVINA

    LEDVINA New Member

    Публикаций:
    0
    Регистрация:
    7 апр 2005
    Сообщения:
    22
    Адрес:
    Czech Republic
    Ну что же, будем нещадно бороться!!