Recently, I encountered an issue with floating-point numbers.
code:
1 | fld dword ptr ds:[esi+1E4] |
and
1 | esi+1E4 = 02FCE9D4 |
The following is its memory:
1 | 02FCE9D4 00 C0 2B 45 00 C0 2B 45 00 00 00 00 00 00 00 00 .?E.?E........ |
After execution this code:
1 | fld dword ptr ds:[esi+1E4] |
watches:
1 | ST0 = 2748.00000000000. |
I would like to know how ST0 equals 2748?
In the end, it’s all about the representation of floating-point numbers. According to the IEEE standard, the first bit is the sign bit, the next 8 bits represent the exponent, and the remaining 23 bits are the mantissa. Considering that it’s little-endian storage, the value of the number 00 C0 2B 45 is 452BC000, which is:
1 | 0100 0101 0010 1011 1100 0000 0000 0000 |
The first bit is 0, indicating it’s a positive number.
The next 8 bits, which is 10001010, 8A, in decimal, is 138. 138 - 127 = 11, indicating the exponent is 11 bits.
And the remaining 23 bits have the value:
1 | 010 1011 1100 0000 0000 0000 |
The leading bit, with the omitted 1, has a value of:
1 | 1010 1011 1100 0000 0000 0000 |
Above 11 bits for the exponent indicate that the position of the decimal point is:
1 | 1010 1011 1100 . 0000 0000 0000 |
Converting to hexadecimal, it’s ABC.000. Converting to decimal, it’s 2748.00000000.