简体   繁体   English

ASM中的浮点数

[英]floating point numbers in ASM

In last days I was playing with C++, ASM and inline ASM. 在过去的几天里,我在玩C ++,ASM和内联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. 现在,我正在尝试使用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. 我在Google上搜索,但没有找到对我有用的东西。 Can anybody explain me real numbers in ASM and can anybody explain me this code? 有人可以向我解释ASM中的实数吗?有人可以向我解释此代码吗? Please help me. 请帮我。

This is what the compiler did with your code: 这是编译器对您的代码所做的:

The compiler recognized “0.058” as a floating-point literal. 编译器将“ 0.058”识别为浮点文字。 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. 然后,它认识到您正在将此双精度值分配给一个单精度对象(浮点数A,而不是双精度A),因此它不需要完整的双精度值。 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. 产生的编码可能是0x3d6d9168,这是单精度.058的通用IEEE 754编码。

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. 在编译器生成的汇编代码中的某个位置,编译器生成了一条指令(向汇编程序的指令),该指令将0x3d6d9168值存储在内存中。 (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]”. 另外,编译器生成了fld指令“ 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. 自从我使用这种形式的汇编已经有一段时间了,所以我可能略有偏离,但是我相信指令说“将数据段(DS)寄存器用作基址,将0x415744用作段内的偏移量。 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. fstp指令“ fstp dword ptr [ebp-8]”的意思是“取扩展基址指针(EBP)寄存器的内容并减去8。该值是指向双字的指针。 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. 请注意,0x415744与浮点值无关。 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. 这两条指令从内存中的只读位置加载常量值并将其存储到[ebp-8],这是编译器决定将值保留在变量A中的位置。EBP通常是用于引用堆栈中的位置,因此编译器几乎可以肯定地在此函数的堆栈帧中预留了一些内存来保存变量的值。

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? 启用优化后,编译器可能不会费心将浮点值实际存储在分配给A的内存中。这是因为您没有立即对值进行任何处理,只是将其存储在A中。但是我们已经知道值并将其存储在其他位置,那么为什么要复制它呢? 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. 取而代之的是,在代码的稍后位置,您实际使用A的值,然后编译器将从只读存储器中加载它,并将其直接用于计算。 (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.) (并非总是这种情况;您可以编写要求编译器进行复制的代码,因为根据传递给它的参数或其他因素,您的代码可能采用多种可能的路径之一,并且编译器需要进行复制以确保正确的数据用于遵循的路径。但是,通常,您不应期望在编写的C代码和编译器生成的汇编指令之间找到完全匹配的代码。)

The first line loads constant float value 0.058 to the FPU stack. 第一行将恒定浮点值0.058加载到FPU堆栈。 The second line copies the top of FPU stack to the CPU stack, addressed by ebp-8. 第二行将FPU堆栈的顶部复制到CPU堆栈,地址为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. 您可以在以下位置阅读有关FPU的说明: http : //maven.smith.edu/~thiebaut/ArtOfAssembly/CH14/CH14-4.html或任何其他Assembly参考。

Edit. 编辑。

dword ptr [ebp-8] copies the top of FPU stack to DWORD-size local variable on the stack. dword ptr [ebp-8]将FPU堆栈的顶部复制到堆栈上DWORD大小的局部变量。 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. 从程序集参考中,EBP(基本指针):程序集功能将基本指针设置为等于堆栈指针,然后将其自己的内部变量放在堆栈上。 From that point on, the function refers to its parameters and variables relative to the base pointer rather than the stack pointer. 从那时起,函数引用相对于基本指针而不是堆栈指针的参数和变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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