0

I need to modified an random number generator using rdrand(only), It implemented in c code as follows.

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

Now i need to modify such that it returns only if carry flag is set. (According to rdrand documentation).I think it can be implimented by jc instruction,but don't know how to use inside __asm__ volatile.please help me.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
coddygeek
  • 125
  • 1
  • 12
  • in setc %1 what is %1 and is it return only if carry flag set@Thiru Shetty – coddygeek Oct 26 '18 at 07:22
  • is this arm or x86 ? – ntshetty Oct 26 '18 at 07:25
  • 1
    Why not just use the intrinsic from ``? `if (_rdrand64_step(&r) == 0) { /* Unable to generate random number */ }` (Might require compiling with `-mrdrnd` or an appropriate `-march=` setting). – Shawn Oct 26 '18 at 07:26
  • 1
    @ThiruShetty: gcc6 and later can have flag outputs from asm statements ([Using condition flags as GNU C inline asm outputs](https://stackoverflow.com/q/30314907)). That would avoid doing a `setc` and then having the compiler use `test al,al` on the result. which is just dumb. (But using intrinsics would be better anyway to just totally avoid the problem.) And it's also better than doing a `jc` inside the asm, even if you use `asm goto` or something to jump to a `return 0` or `return 1` like the Linux kernel does in a few places for branching inside inline asm. – Peter Cordes Oct 26 '18 at 07:27
  • @PeterCordes agree with you.. let me delete my post – ntshetty Oct 26 '18 at 07:28
  • currently have no permission to use intrinsic in our sdk @Shawn – coddygeek Oct 26 '18 at 08:09
  • 1
    You can check [this](https://stackoverflow.com/questions/3898435/labels-in-gcc-inline-assembly). Or just try this `__asm__ volatile ( "1%=: \n\t" "rdrand %0\n\t" "jnc 1%=\n\t" : "=r"(r) : :);` – randomeval Oct 26 '18 at 08:49
  • what is the meaning off this assembler template i reffered gcc docs of extended asm but it seems complex,i understood that here %0 is input.But what 1% does.what this jnc 1%=\n\t means ?,also what 1%=: ? – coddygeek Oct 26 '18 at 09:34
  • With GCC 6(or later) as Peter suggested you could write it as `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; }` With optimisations on (assuming 64-bitcode) it should reduce to a function that is like `looplabel: rdrand %rax` `jnc looplabel` `ret` here _RAX_ would be any register the compiler chooses. – Michael Petch Oct 26 '18 at 22:52
  • If you are writing production code (and you can't use intrinsics) and are new to the nuances and complexities of inline assembly I'd recommend against inline assembly and would suggest you simply write an assembly module that contains similar assembly code to: `_rdrand:` `rdrand %rax` `jnc _rdrand` `ret` . If you get inline assembly wrong it may be a maintenance nightmare to track down the bugs. – Michael Petch Oct 26 '18 at 23:07

0 Answers0