Gcc Inline Assembler - Не Пойму Как Правильно Сделать

Тема в разделе "Общие вопросы по С и С++", создана пользователем EugenOS, 11 июл 2013.

  1. EugenOS

    EugenOS Active Member

    Регистрация:
    22 июл 2007
    Сообщения:
    27
    Симпатии:
    0
    Добрый день всем.
    С GCC работаю впервые. Натолкнулся на проблему. Не знаю как передать в GCC параметром в инлайн ассемблер, константу.
    То есть. Хочу сделать ROL (сдвиг циклический) в виде макроса.

    Для того чтоб меньше путаться, после энного времени мучений, уже разбил все на отдельные строчки.
    Код (C++):
    #define dd0(x)   asm("movl %0, %%eax" :: "d"(x))
    #define dd1(shift) asm("roll $%0, %%eax" :: "d"(shift))
    #define dd2(x)   asm("movl %%eax, %0" :"=d"(x) )

    #define rolb(x,shift) dd0(x);\
    dd1(shift);\
    dd2(x)
    так вот, rolb (rc,9); где rc - переменная типа unsigned long, ругается:
    Error: illegal immediate register operand %edx

    Как я понял это из-за того что во втром макросе shift - константа. как это правильно написать. я чего-то не пойму.
     
  2. EugenOS

    EugenOS Active Member

    Регистрация:
    22 июл 2007
    Сообщения:
    27
    Симпатии:
    0
    в таком виде заработало, переделывать в один макрос не стал.

    Код (C++):
    #define dd0(x)   asm("movl %0, %%eax" :: "d"(x))
    #define dd1(shift) asm("roll %0, %%eax" :: "i"(shift))
    #define dd2(x)   asm("movl %%eax, %0" :"=d"(x) )

    #define rolb(x,shift) dd0(x);\
    dd1(shift);\
    dd2(x)
     
  3. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    шикарно что сам решил проблему, но я бы расстроился если мне пришлось поддерживать такой код.
    чем тебе не подошла обычная inline функция? - зачем эти макросы?
     
  4. EugenOS

    EugenOS Active Member

    Регистрация:
    22 июл 2007
    Сообщения:
    27
    Симпатии:
    0
    в данном месте расположен код, который должен очень быстро работать. кроме того там код портированный из асма контроллера.
    и макросы были и в исходном коде. (хеш функция) - так проще было портировать.

    обычно для циклического сдвига я использую такую конструкцию:

    Код (C++):
    #define roll(x,y) ( (x << y) | (x >> (32-y) )
    ну или инлайн:

    Код (C++):
    unsigned long ( unsigned long x, char y ){ return ( (x << y) | (x >> (32-y) ); };
    но здесь было критично по времени работы. а на такие макросы "построчно" раскладывал, когда понял что не компилится внутри макроса. пришлось разбивать. чтоб увидеть в какой строке проблема.
     
  5. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    EugenOS
    какая разница между inline и макросом в этом случае?
    замена макросов произойдет на этапе препроцессорной обработки, а inline - на следующем )
    в любом случае на месте обращения к макросу или вызова inline функции будет стоять
    ( (x << y) | (x >> (32-y) );
    Или я не прав?
     
  6. EugenOS

    EugenOS Active Member

    Регистрация:
    22 июл 2007
    Сообщения:
    27
    Симпатии:
    0
    разница будет, если использовать например так(пример абстрактный, от балды):

    Код (C++):
    #define OFFSET 20
    ...
    rol( x,  OFFSET + 5 )
    rol( x1, OFFSET + 6 )
    ...
    P.S. во сяком случае на многих компиляторах под микроконтроллеры
     
  7. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    препроцессор заметит это на
    Код (Text):
    #define OFFSET 20
    ...
    rol( x,  20 + 5 )
    rol( x1, 20 + 6 )
    ...
    никаких вычислений он делать не будет.

    Затем оптимизирующий компилятор вычислит константные выражения, но он точно также сработает если написать
    Код (Text):
    const int OFFSET = 20;
    ...
    rol( x,  OFFSET + 5 )
    rol( x1, OFFSET + 6 )
    Ну должен сработать также. Если есть возможность - проверь пожалсто, будет ли разница под МКК - мне интересно )
     

Поделиться этой страницей