Множественная инструкция по сборке с использованием asm volatile в коде c

Мне нужно изменить генератор случайных чисел, используя rdrand (только), Это реализовано в коде c следующим образом.

uint64_t _rdrand(void)
{
        uint64_t r;
            __asm__ volatile("rdrand %0\n\t" : "=r"(r));
                return r;
}

Теперь мне нужно изменить так, чтобы он возвращался, только если установлен флаг переноса. (Согласно документации rdrand) Я думаю, что это можно сделать с помощью инструкции jc, но не знаю, как использовать внутри __asm__ volatile. Пожалуйста, помогите мне.

в setc% 1 что такое% 1 и возвращается ли он, только если установлен флаг переноса @ Thiru Shetty

coddygeek 26.10.2018 09:22

это рука или x86?

ntshetty 26.10.2018 09:25

Почему бы просто не использовать встроенный от <immintrin.h>? if (_rdrand64_step(&r) == 0) { /* Unable to generate random number */ } (может потребоваться компиляция с -mrdrnd или соответствующей настройкой -march=).

Shawn 26.10.2018 09:26

@ThiruShetty: gcc6 и более поздние версии могут иметь выходные данные флагов из операторов asm (Использование флагов условий в качестве встроенных asm-выходов GNU C). Это позволит избежать выполнения setc и последующего использования компилятором test al,al для результата. что просто глупо. (Но в любом случае использование встроенных функций было бы лучше, чтобы полностью избежать проблемы.) И это также лучше, чем делать jc внутри asm, даже если вы используете asm goto или что-то еще для перехода на return 0 или return 1, как это делает ядро ​​Linux в некоторых случаях. места для разветвления внутри inline asm.

Peter Cordes 26.10.2018 09:27

@PeterCordes согласен с вами .. позвольте мне удалить мой пост

ntshetty 26.10.2018 09:28

в настоящее время нет разрешения на использование встроенного в нашем SDK @Shawn

coddygeek 26.10.2018 10:09

Вы можете проверить это. Или просто попробуйте этот __asm__ volatile ( "1%=: \n\t" "rdrand %0\n\t" "jnc 1%=\n\t" : "=r"(r) : :);

randomeval 26.10.2018 10:49

в чем смысл этого шаблона ассемблера? Я сослался на документы gcc для расширенного asm, но это кажется сложным, я понял, что здесь вводится% 0. Но что делает 1%. что означает этот jnc 1% = \ n \ t? 1% =:?

coddygeek 26.10.2018 11:34

С GCC 6 (или более поздней версии), как предложил Питер, вы могли бы написать его как uint64_t _rdrand(void) { uint64_t r; uint8_t carry; do { __asm__ volatile ("rdrand %1\n\t" : "=@ccc"(carry), "=r"(r)); } while (!carry); return r; }. С оптимизацией (при условии 64-битного кода) он должен уменьшиться до функции, подобной looplabel: rdrand %raxjnc looplabelret, здесь RAX будет любым регистром, который выбирает компилятор.

Michael Petch 27.10.2018 00:52

Если вы пишете производственный код (и не можете использовать встроенные функции) и плохо знакомы с нюансами и сложностями встроенной сборки, я бы рекомендовал не использовать встроенную сборку и предлагал вам просто написать модуль сборки, который содержит код сборки, аналогичный следующему: _rdrand:rdrand %raxjnc _rdrandret. Если вы ошиблись при встроенной сборке, поиск ошибок может стать настоящим кошмаром.

Michael Petch 27.10.2018 01:07
0
10
147
0

Другие вопросы по теме