# Copyright (c) 2014 Robert Clausecker # # rand.s -- use RDRAND to generate either a 0 or a 1 .globl _start .type _start,@function _start: # check if the cpuid instruction is available by trying to # toggle the id flag in the eflags register pushfl mov (%esp),%eax btc $21,%eax # toggle id bit push %eax popfl # check if id bit was saved pushfl pop %eax # load new flags pop %ecx # load original flags xor %ecx,%eax # difference is in %eax bt $21,%eax # check if bit was flipped jnc .Lfailure # if we reach this part, we have a cpuid instruction # next, check if rdrand exists mov $1,%eax # load cpuid leaf 1 cpuid bt $30,%ecx # is rdrnd available? jnc .Lfailure # let's try to get some random data rdrand %ax # don't waste randomness; one bit would suffice jnc .Lfailure # no randomness available # make a character 0 or 1 out of one of the random bits and # print it out and $1,%eax # isolate one bit of randomness add $0x30,%al # 0x30 = '0' push %eax mov $4,%eax # prepare a write system call mov $1,%ebx mov %esp,%ecx # where we placed the data before mov %ebx,%edx # one byte int $0x80 # okay, we're done here. Let's exit mov %ebx,%eax # do an exit system call with status 0 xor %ebx,%ebx int $0x80 .Lfailure: mov $1,%eax # do an exit system call with status 1 mov %eax,%ebx int $0x80 .size _start,.-_start