Task

If your system has a means to generate random numbers involving not only a software algorithm   (like the /dev/urandom devices in Unix),   then:

show how to obtain a random 32-bit number from that mechanism.

Related task
 Random_number_generator_(included)


.equ STDOUT, 1
.equ SVC_WRITE, 64
.equ SVC_GETRANDOM, 278
.equ SVC_EXIT, 93
 
.text
.global _start
 
_start:
	stp x29, x30, [sp, -32]! // allocate buffer space at [sp]
	mov x29, sp
	mov x0, sp
	mov x1, #4
	bl _getrandom // getrandom(&tmp, 4);
	ldr w0, [sp]
	bl print_uint64 // print_uint64(tmp);
	ldp x29, x30, [sp], 32
	mov x0, #0
	b _exit // exit(0);
 
// void print_uint64(uint64_t x) - print an unsigned integer in base 10.
print_uint64:
	// x0 = remaining number to convert
	// x1 = pointer to most significant digit
	// x2 = 10
	// x3 = x0 / 10
	// x4 = x0 % 10
	// compute x0 divmod 10, store a digit, repeat if x0 > 0
	ldr x1, =strbuf_end
	mov x2, #10
1:	udiv x3, x0, x2
	msub x4, x3, x2, x0
	add x4, x4, #48
	mov x0, x3
	strb w4, [x1, #-1]!
	cbnz x0, 1b
	// compute the number of digits to print, then call write()
	ldr x3, =strbuf_end_newline
	sub x2, x3, x1
	mov x0, #STDOUT
	b _write
 
.data
strbuf:
	.space 31
strbuf_end:
	.ascii "\n"
strbuf_end_newline:
.align 4
 
.text
//////////////// system call wrappers
// ssize_t _write(int fd, void *buf, size_t count)
_write:
	mov x8, #SVC_WRITE
	svc #0
	ret
 
// ssize_t getrandom(void *buf, size_t buflen, unsigned int flags=0)
_getrandom:
	mov x2, #0
	mov x8, #SVC_GETRANDOM
	svc #0
	ret
 
// void _exit(int retval)
_exit:
	mov x8, #SVC_EXIT
	svc #0