intrinsic memcpy in WDK

Тема в разделе "WASM.NT.KERNEL", создана пользователем ZrtUybG, 1 май 2007.

  1. ZrtUybG

    ZrtUybG New Member

    Публикаций:
    0
    Регистрация:
    1 май 2007
    Сообщения:
    6
    Раньше я всегда компилировал драйвера в XP DDK. Его компилятор всегда превращает memcpy в rep movsd/movsb. Вчера я поставил WDK, там более новая версия компилятора, и столкнулся с неприятной проблемой - функции memcpy и memset всегда вызываются через импорт, что раздувает код и мешает его работе в базонезависимом модуле.
    http://msdn2.microsoft.com/en-us/library/ms864585.aspx
    Здесь написано, что заставить инлайнить эти функции можно директивой #pragma intrinsic, но она решает проблему лишь отчасти. При укзании в memcpy фиксированого размера в последнем параметре, вставляется rep movsd, ну а если размер задается переменной, то по прежнему вызывается внешняя функция.
    Откатываться к старому компилятору из за этого очень не хочеться, может кто нибудь подскажет, как решить проблему?
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    написать функции самому

    inline void memcpy( void* dst, void* src, size_t len )
    {
    __asm {
    mov esi, src
    mov edi, dst
    mov ecx, len
    rep movsb
    }
    }

    примерно так. или вообще в виде макроса
     
  3. ZrtUybG

    ZrtUybG New Member

    Публикаций:
    0
    Регистрация:
    1 май 2007
    Сообщения:
    6
    Такой вариант работает, да только инлайн получается не очень компактным, хуже чем делал старый компилятор. Да и при обнулении структур наподобии CHAR dll_name[MAX_PATH] = {0}; всеравно вставляется внешний вызов.
     
  4. @Asterisk@

    @Asterisk@ New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2007
    Сообщения:
    7
    А самому сказать компилятору, чтобы использовал intrinsic?

    #if (_MSC_FULL_VER > 13009037)
    #pragma intrinsic (_memcpy)
    #endif

    PS: Так кстати оптимизируются и Interlock операции
     
  5. ZrtUybG

    ZrtUybG New Member

    Публикаций:
    0
    Регистрация:
    1 май 2007
    Сообщения:
    6
    @Asterisk@
    А внимательно прочитать первый пост?

     
  6. @Asterisk@

    @Asterisk@ New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2007
    Сообщения:
    7
    действительно, извини.

    можешь попробовать включить /Ob<n> inline expansion (default n=0), также поиграться со стек гуардом, его тоже добавили в новых компиляторах.
    вот ещё статейка неплохая Криса Касперского, как раз по этой функции: http://www.insidepro.com/kk/024/024r.shtml
     
  7. ZrtUybG

    ZrtUybG New Member

    Публикаций:
    0
    Регистрация:
    1 май 2007
    Сообщения:
    6
    Оказалось что проблема решается очень просто, достаточно определить
    Код (Text):
    1. #define memcpy __movsb
    2. #define memset __stosb
    __movsb и __stosb это встроеные функции vc, генерирующие rep movsb/rep stosb, и при этом достигается лучшая оптимизация, чем при асм вставке (за счет оптимального перераспределения регистров в функции).