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

EugenOS

Active member
22.07.2007
27
0
#1
Добрый день всем.
С 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 - константа. как это правильно написать. я чего-то не пойму.
 

EugenOS

Active member
22.07.2007
27
0
#2
в таком виде заработало, переделывать в один макрос не стал.

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)
 
R

rrrFer

#3
шикарно что сам решил проблему, но я бы расстроился если мне пришлось поддерживать такой код.
чем тебе не подошла обычная inline функция? - зачем эти макросы?
 

EugenOS

Active member
22.07.2007
27
0
#4
в данном месте расположен код, который должен очень быстро работать. кроме того там код портированный из асма контроллера.
и макросы были и в исходном коде. (хеш функция) - так проще было портировать.

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

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

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

rrrFer

#5
EugenOS
какая разница между inline и макросом в этом случае?
замена макросов произойдет на этапе препроцессорной обработки, а inline - на следующем )
в любом случае на месте обращения к макросу или вызова inline функции будет стоять
( (x << y) | (x >> (32-y) );
Или я не прав?
 

EugenOS

Active member
22.07.2007
27
0
#6
разница будет, если использовать например так(пример абстрактный, от балды):

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

rrrFer

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

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