C++ битовые операции

Тема в разделе "LANGS.C", создана пользователем MirrorBlack, 14 мар 2009.

  1. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    Вопрос к знатокам (сам С++ изучаю 5 день после 15 лет ассемблера).
    Есть в языке аналог битовых операции процессора - bt,bts,btc,btr ?
    И вопрос не в тему, как избавиться от функции WinMain, и получить обычный вход в программу?
    Вызвать GetModuleHande и GetCommandLine я и сам в состоянии :)
    С непривычки поражает размер выходного файла в ms vc++...
     
  2. RamMerLabs

    RamMerLabs Well-Known Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    1.426
    MirrorBlack
    а что мешает написать "_asm {}" и использовать те же операции?
    пишешь свою функцию, управление которой будет передаваться при старте программы, и указываешь линкеру: /entry:name_of_function

    опция линкеру /nodefaultlib спасает, но необходимые либы придёться прописывать ручками (всё тому же многострадальному линкеру :)), ну и сборка типа "Release", чтобы убрать отладочную информацию из экзехи.

    я например собираю примерно таким батником:

    Код (Text):
    1. LINK msvcrt.lib /nodefaultlib /nologo /subsystem:console XXXX.obj /entry:_main /pdb:none /machine:I386 /out:"XXXX.exe" /libpath:"тут_путь_к_lib"
    ну доп опции по вкусу
     
  3. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    RamMerLabs
    Если я правильно понял - ответ нет?
     
  4. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Есть такие штуки как intrinsic functions.

    unsigned char _bittest(long *a, long b);
    unsigned char _bittestandcomplement(long *a, long b);
    unsigned char _bittestandreset(long *a, long b);
    unsigned char _bittestandset(long *a, long b);

    Но тогда код становится не кроссплатформенным.

    Для bt x, n подойдет замена x & (1 << n), для остальных нужно реализации посложнее придумывать.
     
  5. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    KeSqueer
    Вот это - то что надо.

    Ценность bt* не в том, что она работает с некой переменной X (для этого обычных логических операций хватит), а в том что она работает с огромными областями памяти.
    Конечно в ежедневном обиходе это практически не нужно.
    Последний раз я пользовался этим при создании HASP эмулятора, а драйверам кроссплатформеность не грозит :)
     
  6. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    MirrorBlack, bt* это инструкция конкретного процессора и ни в ANSI C ни в ISO C++ 98 эквивалента нету.

    Обычно такие вещи делают макросом на С и inline ф-цией на С++. Ессно, надежда на то, что компилер выдаст достаточно быстрый код. При необходимости оптимизации вставляешь __asm (VC++) или __emit (gcc/g++). Ессно, это убивает крос-платформенность - такова цена.
     
  7. ALLeX

    ALLeX Member

    Публикаций:
    0
    Регистрация:
    21 окт 2004
    Сообщения:
    141
    Адрес:
    Ukraine
    MirrorBlack
    Кое что есть в BITIO by Jeremy Collake
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    MirrorBlack
    Для "огромных областей памяти" тоже "обычных логических операций хватит"
    n >> 3 - индекс байта
    n & 3 - индекс бита в байте
     
  9. twgt

    twgt New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    1.494
    http://wasm.ru/forum/viewtopic.php?pid=200011#p200011
     
  10. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    leo
    Так можно ещё и операции с плавающей точкой имитировать икрементом/декрементом...
    Куча кода вместо одной команды - это не кашерно.
     
  11. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    MirrorBlack
    Мануалы по оптимизации от Intel, AMD и Агнера Фога считают иначе ;)

    PS: Да и в бормановском паскале\дельфях битовые операции над множествами (set) и TBits релизованы на логических операциях, а не на тормознутых bt*
     
  12. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    leo
    Честно - не видел мануалов по оптимизации на современные процессоры...
    Всё что попадаось - мхом проросло, а такому доверять стрёмно.
    Кроме того - в ядре windows используется bt* для работы с TSS (а это о многом говорит).
     
  13. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    MirrorBlack
    А зря, очень поучительно... :)

    Да ни о чем особенном. С TSS не так уже много работы, а вот если гонять мегабайтные массивы сразу почувствуется разница.

    [offtop]
    и вообще, с каких пор код мелкософта стал кошерным? Сей продукт жизнедеятельности Билла Гейтса следует хулить и проклинать, это кошерно :):):)
    [/offtop]
     
  14. ozzman2k

    ozzman2k New Member

    Публикаций:
    0
    Регистрация:
    7 июл 2008
    Сообщения:
    10
    bitset в STL довольно удобен в использовании.
     
  15. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    Ustus
    После ответа KeSqueer тему можно было закрывать, но посыпались сообщения о неэффективности операции bt*...
    Вобще я часто встречаю на форумах ситуацию когда спрашивают одно, а им отвечают на посторонние темы.
    Что касается оптимизации, я мелком выложил свои соображения на:
    http://www.wasm.ru/forum/viewtopic.php?id=31712

    Не хочу никого обидеть, но считаю что про оптимизацию кода знают ТОЛЬКО инжинеры Intel и его партнёров (например Microsoft).
    Если говорить об эффективности bt* можно разобрать пример. Надо проверить разрешён ли 406 I/O порт в TSS.
    mov eax,406
    mov edx,TSS
    bt [edx+66h],eax
    Как ЭТО сделать быстрее?
    Не представляю что можно делать такими с массивами с помощью bt* :)
    [offtop]
    К Windows у меня отношение тоже не однозначное (как у человека который провёл долгие месяцы изучая её кишки/ядро с SoftIce). Но тем не менее мы на нём работаем и зарабатываем на хлеб с икрой (я уж точно).
    [/offtop]
     
  16. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    MirrorBlack
    Так на вопрос ответили, а тему зачем закрывать? тема развивается... это нормально. :)

    Почему ИНЖЕНЕРЫ должны вообще знать слово "оптимизация" ?
    И вообще, откуда такие предрассудки? Все, кому надо, все всё знают... В крайнем случае всегда можно поковырять руками. :) Они и не скрывают ничего.

    Дык, как обычно :) test, and + сдвиги. Вы будете смеяться, но так быстрее. :)

    Ну, мало ли фанатиков... :) главное вовремя предупредить... И вообще, когда всуе упоминают аццкие команды - BT, LOOP, INC, XCHG и тому подобных - сразу являются служители света, дабы прекратить сие непотребство и почувствовать себя нереально умными. :) И я тоже, че я хуже всех? :):) Так что не ломайте кайф :):):)
     
  17. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    Ustus
    IsPortEn proc NumBt:lol: WORD,TSS:lol: WORD
    mov eax,NumBt
    mov edx,TSS
    bt [edx+66h],eax
    setc al
    movzx eax,al ;Для кашерности
    ret
    IsPortEn endp
    Я свой код привёл. Можно посмотреть Ваш?

    Раньше самым ценным было золото, сейчас информация. Поэтому "ВСЕ" знают только то, что им положено знать.

    И я о том же. Главное предупредить что нет плохих команд, а есть их плохое использование.
     
  18. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Код (Text):
    1. IsPortEn    proc    NumBt:DWORD, TSS:DWORD
    2.         mov edx,NumBt
    3.         mov ebx,TSS
    4.         mov ecx,edx
    5.         shr edx,5       ; Dword offset
    6.         and cl,1Fh      ; Bit number in dword
    7.         mov eax,[ebx+edx*4]
    8.         shr eax,cl
    9.         and eax,1
    10.         ret
     
  19. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    cppasm
    И так действительно пишут???
    Мало того что код не читаемый, так ещё и ebx используется.
    По хорошему надо добавить push ebx и pop ebx.
    Т.е. использовать 4 регистра вместо 2, проводить 2 операции сдвига и 2 логические операции это лучше?
     
  20. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Как видишь.
    Ну ты же не говорил откуда код вызываться будет, какое соглашение о вызовах.
    Замени везде ebx на eax - и не надо будет push ebx/pop ebx
    И что в нём такого нечитаемого?
    Ты посмотри код, генерируемый Intel C++ Compiler, тогда поймёшь что такое нечитаемый код :)
    А вот в плане быстродействия ему упрекнуть трудно.
    А ты померяй.