• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

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

  • Автор темы EugenOS
  • Дата начала
E

EugenOS

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

EugenOS

в таком виде заработало, переделывать в один макрос не стал.

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

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

EugenOS

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

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

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

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

EugenOS

разница будет, если использовать например так(пример абстрактный, от балды):

C++:
#define OFFSET 20
...
rol( x,  OFFSET + 5 )
rol( x1, OFFSET + 6 )
...

P.S. во сяком случае на многих компиляторах под микроконтроллеры
 
R

rrrFer

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

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

Ну должен сработать также. Если есть возможность - проверь пожалсто, будет ли разница под МКК - мне интересно )
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!