Click here to Skip to main content
15,897,273 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
ok so I declare :
double d=2644;
double as=24.166496
and then,using ollydebug examine the memory contents of the program.
the program is using a strange (to me ) method to write this number to the memory using the FLD and FSTP instructions.
the assembly code coresponding to the two c++ commands is
FLD DWORD (source)
FSTP QWORD (destination)
FLD QWORD (source)
FSTP QWORD (destination

why is the first variable treated as a DWORD at first and at QWORD later (first two commands) ??
also,the d variable is 0x40a4a80000000000 in memory.
when storing the value 2643 the memory is0x40a4a60000000000
how is the fpoint number converted to binary ?
I thought it was an excess but it doesnt seem like it.
finally,the number stored in the ST0 stack is 2644.0000000000015000 .
and it's hex representation is 400AA540000000000000
why isn't it simply 2644.0 and why is the value at ST0 different than that of memory ?
thank you !
Posted

1. Because you only need a 16 bit word (or more accurately, 12 bits) to store the number 2643. However, memory access is faster when using a word-size that matches the native word size of the operating environment. So, it's better to load a 4-byte int that holds 2643 than it is to load a 2 '(or any other value) byte int. (when operating in 32 bit mode)

2. The number is stored by the fpu in IEEE 754 format. You can read more about it (IEEE754) on the wiki page,or any other you find better suited to your needs. http://en.wikipedia.org/wiki/IEEE_floating_point[^]

3. Because you can't represent all floating point numbers precisely. Some you can represent exactly - others you can represent with a small degree of error. The error in the case you show 2644.0000000000015000 is (15 parts in 100 billion) too large - an entirely trivial amount is most circumstances. This is equivalent to 3 teaspoons of water too much in an order of 100,000 cubic meters of water.

3b. OllyDbg knows what was loaded into ST0, and so displays his value, rather that the exact value held in the register, thus indicating intent in a clear manner to the reverse-engineer/debugger.


#3 is the reason that we don't represent money with floating point numbers - their is in inherent inaccuracy with them.
 
Share this answer
 
With FPU commands, the DWORD and QWORD indicate the type of the number stored in memory (single or double precision). In your case the compiler decided to store the number 2644 in single precision.

The FLD command will load the number from memory, convert it to the internally used 80 bit double extended precision format, and push it onto the FPU stack. The FSTP command will convert the value on top of the stack to the type specified by the memory size, store it to memory, and pop the stack.

You may now wonder why the compiler uses FPU commands rather than coyping memory content. Using the FPU commands here reduces data memory (storing one value using 4 bytes instead of 8 bytes) and also program memory for 32 bit applications (using two FPU commands requires less code than copying two 64 bit values). It is also faster because FPU commands are executed independently of normal CPU instructions (as long as no synchronization between FPU and CPU is required which is performed by the FWAIT instruction). If you enable usage of SSE/SIMD extensions, the compiler may also use these to copy floating point values.

To compare numbers in memory reading the the raw hex data, you must know the format and convert numbers yourself if they did not have the same precision.

Some good readings are:
Wikipedia IEEE floating point[^] article.
Intel® 64 and IA-32 Architectures Software Developer Manuals[^]:
Volume 1, Chapter 4, Section 4.2.2: Floating-Point Data Types
Volume 1, Chapter 8: PROGRAMMING WITH THE X87 FPU.
Volume 2 contains the instruction set reference including the FPU commands.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900