Challenge #20

Let’s do challenge #20, because #19 it’s quite tricky will have it as a WIP 😅. Challenge #20 can be found on the original website. Here is the assembly code to understand

f4:
.LFB40:
        sub     rsp, 8
        call    rand
        ;; convert rand generated number to int
        cvtsi2ss        xmm0, eax
        mulss   xmm0, DWORD PTR .LC0[rip]
        add     rsp, 8
        ret
.LC0:
        .long   805306368

According to the description we are dealing here with floating point numbers. Let’s start the analysis of it.

Analysis

We first have a call to rand to generate a random number, followed by an instruction cvtsi2ss which convert the generated random number into floating number. Later we compute the r * 4.656612873077392578125E-10, where r is our recently generated rand number. The code in C would be

float f(void)
{
    return float()rand() * 4.656612873077392578125E-10;
}

Yes, you noticed right? I multiplied by 4.656612873077392578125E-10 instead of 805306368, for understanding that you should read Wikipedia IEEE_754 article. Also this online converter will help you, if you supply the hex representation of 805306368, which is 0x30000000 you will get 4.65661287308e-10.

Given that rand will give us a random number from [0, RAND_MAX], RAND_MAX in my OS has value 2147483647, this operation will give us values from [0, 0.9999999995348987]. One thing missing in this code is the seed of rand function, so it will be always evaluated with seed 1.

Formal description

Generate numbers from 0 to 1.