О команде bswap...

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

  1. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Здесь на форуме читал про простую задачу: инверсия битов числа из биг-ендиан в литле-ендиан и наоборот. Там писалось, что обычный программист напишет цикл, продвинутый - использует апи из вс2-32, а тот кто пишет на асме использует bswap.

    Мне хотелось бы узнать, знает ли кто-нибудь как использовать эту команду в ассемблерной вставке для синтаксиса AT&T, чтобы написать примерно такую функцию на Си++:

    void InvertBits (int& num)
    {
    asm ("bswap ???,???");
    }

    или, того лучше оформить это макросом...
     
  2. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    Praetor11
    inline надо еще, макросом не надо
     
  3. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Ну продемонстрируйте !!!!

    Все программы уже написаны. Зачем писать?)
     
  4. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    я вам сказал как будет правильнее с точки зрения с++ а дальге под свой компилятор/ассемблер сами уже...

    вот и пишите
     
  5. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    bswap 1 короче, 2 быстрее, 3 короче к написанию (в случае с ассемблером)
     
  6. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    ADD(редактирование верните)
    4 работает с любым регистром (а не только с eax, куда возвращается результат)
    5 если не изменяет память, то bswap появилась раньше чем написали API функцию, хотя скорее всего память мне изменяет.
     
  7. Guest

    Guest Guest

    Публикаций:
    0
    #define BSWAP(x) __asm {mov eax, x} __asm {bswap eax} __asm{mov x, eax}
     
  8. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Млин, стока ответов и ни одного толкового. Ну хоть кто нибудь напишите как использовать эту команду в инлайн варианте, или в асм варианте синтаксиса AT&T.

    Тут вообще есть те, кто эту команду хоть раз использовал?)
     
  9. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    ОО спасибо тебе im1111, а теперь можешь тоже самое только в синтаксисе AT&T)) Как переобозначить регистр я знаю (добавлением %) а вот переменную он не хочет признавать!
     
  10. Guest

    Guest Guest

    Публикаций:
    0
    Не на чем проверить (
    Смотря какой компиль, он может и не позволит такой трюк.
    Вот 2 варианта:

    __inline VOID BSWAP(PDWORD x)
    {
    __asm
    {
    mov ecx, x
    mov eax, dword[ecx]
    bswap eax
    mov dword[ecx], eax
    }
    }

    __inline DWORD BSWAP(DWORD x)
    {
    __asm
    {
    mov eax, x
    bswap eax
    }
    }

    Первый создает довольно избыточный код в MSVC 9, а второй компиль инлайнит очень хорошо, но использовать не удобно -> x=BSWAP(x);
     
  11. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Попытался перевести на этот долбанутый синтаксис, вот что вышло:

    Код (Text):
    1. #define BSWAP(x) asm ("movl x, %eax");  asm ("bswap %eax"); asm("movl %eax, x");
    Но при попытке использования так:

    int x = 5;
    int y = BSWAP (x);

    получаю собщение от линкера, что символ x - undefined reference. (( Блин осталось чуть-чуть..кто силен в асме американской телефонной компании.
     
  12. Guest

    Guest Guest

    Публикаций:
    0
    Если компиль совсем тупой, то лучше вообще так:

    __inline DWORD BSWAP(DWORD x)
    {
    __asm
    {
    mov eax, x
    bswap eax
    mov x, eax
    }
    return x;
    }
     
  13. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Мой компиль от gcc вообще не понимает адекватный асм. Ругаеца на то что вы предлагаете в каждой строчке(( На тот код что мне удалось перевести ругаецо только в том что там переменная, если подставляю число ($0x4) допустим, то все компилится... И нигде пока не могу найти как работать с переменной ...Уже подумываю об htons, правда мне надо 4-х байтное число перевернуть...
     
  14. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    Воть, попробуйте вкусненького:
    Код (Text):
    1. #include <stdio.h>
    2.  
    3. #define _BSWAP(x) asm ("movl %%eax, %1\n\t" \
    4.                        "bswap %%eax\n\t" \
    5.                        "movl %0, %%eax\n\t" \
    6.                        :"=r"(x) \
    7.                        :"r"(x) \
    8.                        :"%ecx")
    9.  
    10. int main()
    11. {
    12.   printf("hello asm!\n");
    13.   unsigned long var_dword = 0x000099BB;
    14.   printf("var = 0x%X\n",var_dword);
    15.   _BSWAP(var_dword);
    16.   printf("result = 0x%X\n",var_dword);
    17.   return 0;
    18. }
     
  15. semen

    semen New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2004
    Сообщения:
    334
    Адрес:
    Russia
    Praetor11
    Как я понял ты компилишь gcc, в нем есть интринзик на эту инструкцию, лучше использовать его. Если gcc новый, то можно писать совместимо с msvc - интринзик _byteswap_ulong.
     
  16. Praetor11

    Praetor11 New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2009
    Сообщения:
    80
    Термосинтез, огромное вам спасибо за хороший пример, он отлично компилируется и линкуется с одной только маленькой проблемой - не работает (, т.е. число не меняется...

    Не могли бы вы мне также объяснить почему перед именами регистров ставится два знака % и что означают магические строки: :"=r"(x) \ :"r"(x) \ :"%ecx")

    Я конечно понимаю что это глупые вопросы об асме, но найти ответы на них в гугле крайне сложно, потому как данный синтаксис плохо описан (полно по обычному асму).

    Код (Text):
    1. Как я понял ты компилишь gcc, в нем есть интринзик на эту инструкцию, лучше использовать его. Если gcc новый, то можно писать совместимо с msvc - интринзик _byteswap_ulong
    Да у меня гсс, правда не самый последний (хотя могу скачать и новее, но ради одной команды думаю глупо). Проверил: мой компиль ругаецо на это инструкцию, но это неудивительно в силу его возраста.
     
  17. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    Praetor11
    Как собирать: gcc -g MyProgBswap.c -o MyProgBswap
    Обрати внимание что исходник должен быть с расширением ".с"
    Про магические строки - приложу статью маленькую на интересную вам тему. Статья моя, но недописанная, и сейчас некогда дописывать.
     
  18. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    Praetor11
    5. Extended Asm.
    http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
     
  19. Microedition

    Microedition Active Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    814
    Не битов, а байтов.
     
  20. semen

    semen New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2004
    Сообщения:
    334
    Адрес:
    Russia
    Вообще бсвап юзается для скорости обычно, а это значит лишние movl там никчему, аналогом интринзика будет:
    asm ("bswap %1" : "=r" (i) : "0" (i));
    если не ошибся нигде.