FLD浮点指令 [英] FLD floating-point instruction

查看:465
本文介绍了FLD浮点指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH14/CH14-4.html#HEADING4-5

14.4.4.1 FLD指令
fld mem_32
fld mem_64 [bx]

14.4.4.1 The FLD Instruction
fld mem_32
fld mem_64[bx]

我的目标是将常数10存储到我的fPU堆栈中. 为什么我不能这样做?

My objective is store a constant 10 into my fPU stack. Why I cant do this?

__asm
{
  move bx, 0x0004;
  fld dword ptr[bx] or fld bx;


  //-------
  fld 0x004; //Since it is 32 bits?
  fild 0x004;     
}

推荐答案

此处至少有三件事可能出错.一种是汇编器的语法.第二个是指令集架构.第三个是内存模型(16位vs 32位,分段vs平面).我怀疑所提供的示例针对的是16位分段体系结构,因为8087是从那个时代开始的,但是c ++编译器主要是在386+保护模式之后出现的.

At least three things can go wrong here. One is the syntax of the assembler. The second is instruction set architecture. The third is the memory model (16 bit vs 32 bit, segmented vs flat). I suspect that the examples provided are targeted at 16-bit segmented architecture as the 8087 is from those ages, but c++ compilers mainly arrived after 386+ protected mode.

8087 FPU不支持在通用寄存器(GPR)和浮点堆栈之间移动数据的指令.基本原理是浮点寄存器使用32位,64位或80位,而GPR仅16位宽.而是直接从内存间接移动数据.

The 8087 FPU does not support instructions that move data between general purpose registers (GPR) and floating point stack. The rationale is that floating point registers use 32, 64 or 80 bits, while the GPRs are only 16 bit wide. Instead on moves data indirectly from memory.

示例fld myRealVar假定已提供标签(具有宽度):

The example fld myRealVar presupposes that a label (with a width) has been provided:

 .data
 myRealVar:    .real8  1.113134241241
 myFloat:      .real4  1.1131313
 myBigVar:     .real10 1.1234567890123456
 myInt:        .word   10
 myInt2:       .word   0
 myBytes:      .byte   10 dup (0)   ;// initializes 10 bytes of memory with zeros

 .text        
 fld      myRealVar;  // accesses 8 bytes of memory
 fild     myInt;      // access the memory as 16 bits
 fild     myBytes;    // ## ERROR ##   can't load 8-bits of data
 fild     dword ptr myBytes;  // Should work, as the proper width is provided

首先请注意,这些示例假定数据属于段.data,并且已经使用

Notice first that these examples assume that data belongs to a segment .data and that one has initialized the segment with

 mov  ax, segment data;  //
 mov  ds, ax

仅在此之后,内存位置0x0004可能包含常数10.我强烈怀疑该模型在嵌入式c ++系统中不可用.同样,这里的汇编器必须足够聪明,才能将每个标签与提供的宽度相关联并在指令中进行编码.

Only after that the memory location 0x0004 could possibly contain the constant 10. I strongly suspect that that model isn't available with your inline c++ system. Also here the assembler has to be smart enough to associate each label with the provided width and encode that in the instruction.

将整数加载到FPU中的一种方法是使用堆栈:

One way to load the integer into FPU is to use the stack:

 push bp                 // save bp
 mov  ax, 10
 push ax
 mov  bp, sp             // use bp to point to stack
 fld  word ptr [bp]
 pop  ax                 // clean the stack and restore bp
 pop  bp
 .. or ..
 mov  bx, 10
 push bx
 mov  bx, sp
 fld  word ptr ss:[bx]   // notice the segment override prefix ss
 pop  ax                 // clean the constant 10

在32位体系结构中,可以直接使用esp指向栈顶,这可能是c ++编译器的情况:

In 32-bit architecture one can directly use esp to point the top of stack, which is probably the case with your c++ compiler:

 sub  esp, 4
 mov  dword ptr [esp], 10  // store the integer 10 into stack
 fild  dword ptr [esp]     // access the memory
 add  esp, 4               // undo the "push" operation

某些内联汇编器可能能够使用局部变量,并自动将标签替换为ebp/esp寄存器和正确的偏移量:

Some inline assemblers may be able to use local variables and automatically substitute the label with ebp/esp register and the correct offset:

 int f1 = 10;
 void myfunc(float f2) {
     double f = 10.0;
     __asm {
        fild f1   // encoded as fild dword ptr [xxx]
        fld f     // encoded as fld qword ptr [esp + xxx]
        fld f2    // encoded as fld dword ptr [esp + xxx]
     }
 }

这篇关于FLD浮点指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆