简体   繁体   中英

floating point numbers in ASM

In last days I was playing with C++, ASM and inline ASM. I know how to access basic variables in memory and similar things. Now I'm trying to work with floating-point numbers in ASM. I have disassembled this code:

float A = 0.058;

and I have this result:

 fld         dword ptr ds:[00415744h]  
 fstp        dword ptr [ebp-8]

But I don't understand this code. I was searching on google but I have not found anything usable for me. Can anybody explain me real numbers in ASM and can anybody explain me this code? Please help me.

This is what the compiler did with your code:

The compiler recognized “0.058” as a floating-point literal. It analyzed the string to calculate the value it represented and to encode that value as a double-precision floating-point value. Then it recognized that you were assigning this double-precision value to a single-precision object (float A, not double A), so it did not need the full double-precision value. So the compiler converted it to single-precision. The encoding that resulted was probably 0x3d6d9168, which is the common IEEE 754 encoding for .058 in single-precision.

Somewhere in the assembly code the compiler generated, the compiler generated a directive (an instruction to the assembler) that causes that value, 0x3d6d9168, to be stored in memory. (This is a complicated process; the assembler writes the value to the object file it produces, as part of various data to be part of the program's image. That data will be loaded into memory when the program is prepared for execution or when the program first tries to access that portion of memory.)

Additionally, the compiler generated the fld instruction, “fld dword ptr ds:[00415744h]”. It has been a while since I used that form of assembly, so I may be off slightly, but I believe that instruction says ”Use the Data Segment (DS) register as a base address and 0x415744 as an offset within the segment. That combination is a pointer to a double-word. Load four bytes from there to the floating-point stack. (The floating-point stack is a special set of registers inside the processor.)

The fstp instruction, “fstp dword ptr [ebp-8]”, means “Take the contents of the Extended Base Pointer (EBP) register and subtract 8. That value is a pointer to a double-word. Store four bytes from the floating-point stack to that double-word, and pop the item off the floating-point stack.”

Note that 0x415744 has nothing to do with the floating-point value. It is the address in memory where the constant value was stored. These two instructions are loading the constant value from a read-only location in memory and storing it to [ebp-8], which is the place in memory where the compiler has decided to keep the value in your variable A. The EBP is commonly used to refer to locations in the stack, so the compiler has almost certainly set aside some memory in the stack frame of this function to hold values of your variables.

I suspect you compiled this code with optimization turned off. When optimization is turned on, the compiler would likely not bother to actually store the floating-point value in the memory assigned for A. This is because you are not doing anything with the value immediately, just storing it in A. But we already know the value and have it stored elsewhere, so why bother copying it? Instead, at some later location in the code, where you actually use the value of A, the compiler would then load it from the read-only memory and use it directly in calculations. (This is not always the case; you can write code that requires the compiler to do some copying because your code might take one of multiple possible paths depending on parameters passed to it or other factors, and the compiler needs to do the copying to ensure the right data is used for the path that is followed. However, in general, you should not expect to find exact matches between C code that you write and assembly instructions that the compiler generates.)

The first line loads constant float value 0.058 to the FPU stack. The second line copies the top of FPU stack to the CPU stack, addressed by ebp-8.

You can read about FPU instructions here: http://maven.smith.edu/~thiebaut/ArtOfAssembly/CH14/CH14-4.html or in any other Assembly reference.

Edit.

dword ptr [ebp-8] copies the top of FPU stack to DWORD-size local variable on the stack. From Assembly reference, EBP (base pointer): Assembly function sets the base pointer equal to the stack pointer and then places its own internal variables on the stack. From that point on, the function refers to its parameters and variables relative to the base pointer rather than the stack pointer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM