`

浮点数类型转换指令

阅读更多
        在浮点寄存器概述一节中对浮点寄存器和浮点传送指令进行了相关介绍,这里将继续给出浮点数和整数数据类型之间以及不同浮点格式之间进行转换的指令集合,它们都是对单个数据值进行操作的标量指令。
        首先来看一下将浮点数转换成整数的指令。

        这些指令把一个从 XMM 寄存器(图中用 X 表示)或内存(图中用带内存范围下标的 M 表示)中读出的浮点值转换成对应的整数类型,并将结果写入一个通用寄存器(如 %rax 和 %ebx 等,图中用带范围下标的 R 表示)。在把浮点值转换成整数时,指令会执行截断,把值向 0 进行舍入。
        将整数转换为浮点数则使用下面的指令。

        这组指令使用了不太常见的三操作数格式,有两个源和一个目的。第一个操作数读自于内存或一个通用目的寄存器。第二个操作数目前可以忽略,通常写成和目的操作数一样,因为它的值只会影响结果的高位字节,而目标必须是 XMM 寄存器,不需要使用高位字节。比如指令“vcvtsi2sdq  %rax, %xmm1, %xmm1”将从寄存器 %rax 读出一个长整数,把它转换成 double 类型,并把结果存放进 XMM 寄存器 %xmm1 的低 8 位字节中。
        而对于不同浮点数格式之间的转换,GCC 的当前版本生成的汇编指令就比较奇怪了。比如,要将一个单精度浮点值转换成双精度,使用的不是类似于“vcvtss2sd  %xmm0, %xmm0, %xmm0”这样直观的指令,而是会使用下面两条指令:
            vunpck1ps    %xmm0, %xmm0, %xmm0    ; Replicate first vector element
            vcvtps2pd    %xmm0, %xmm0           ; Convert two vector elements to double
        其中,vunpck1ps 指令通常用来交叉放置来自两个 XMM 寄存器的值,把它们存储到第三个寄存器中。也就是说,如果一个源寄存器的内容为字 [s3, s2, s1, s0],另一个源寄存器为字 [d3, d2, d1, d0],那么目的寄存器的值会是 [s1, d1, s0, d0]。所以对于上面这种三个操作数都使用同一个寄存器的情况,假设原始寄存器的值为 [x3, x2, x1, x0],那么这条指令会将该寄存器的值更新为 [x1, x1, x0, x0]。而 vcvtps2pd 指令则会把源 XMM 寄存器中的两个低位单精度值扩展成目的 XMM 寄存器中的两个双精度值,因此对之前的 [x1, x1, x0, x0] 结果应用这条指令会得到值 [dx0, dx0],这里 dx0 表示将 x0 转换成双精度后的结果。因而上面两条指令的最终效果就是将原始的 %xmm0 低位 4 字节中的单精度值转换成双精度值,再将其两个副本保存到 %xmm0 中。
        同理,对于把双精度转换为单精度,GCC 也没有直接使用指令“vcvtsd2ss  %xmm0, %xmm0, %xmm0”,而是会产生类似的代码:
            vmovddup    %xmm0, %xmm0    ; Replicate first vector element
            vcvtpd2psx  %xmm0, %xmm0    ; Convert two vector elements to single
        假设这些指令开始执行前寄存器 %xmm0 保存着两个双精度值 [dx1, dx0]。那么, vmovddup 指令会把它设置成 [dx0, dx0],接着 vcvtpd2psx 指令会把这两个值转换成单精度,再存放到该寄存器的低位一半中,并将高位一半设置为 0,得到结果 [0.0, 0.0, x0, x0]。
        以下面的一个浮点转换的 C 函数为例。
double fcvt(int i, float *fp, double *dp, long *lp){
    float f = *fp;
    double d = *dp;
    long l = *lp;

    *lp = (long) d;
    *fp = (float) i;
    *dp = (double) l;
    return (double) f;
}

        则 GCC 生成的 x86-64 汇编代码类似如下。
;double fcvt(int i, float *fp, double *dp, long *lp)
;i in %edi, fp in %rsi, dp in %rdx, lp in %rcx
fcvt:
    vmovss    (%rsi), %xmm0              ; Get f = *fp
    movq      (%rcx), %rax               ; Get l = *lp
    vcvttsd2siq    (%rdx), %r8           ; Get d = *dp and convert to long
    movq      %r8, (%rcx)                ; Store at lp
    vcvtsi2ss  %edi, %xmm1, %xmm1        ; Convert i to float
    vmovss    %xmm1, (%rsi)              ; Store at fp
    vcvtsi2sdq  %rax, %xmm1, %xmm1       ; Convert l to double
    vmovsd    %xmm1, (%rdx)              ; Store at dp
    ; The following two instructions convert f to double
    vunpcklps  %xmm0, %xmm0, %xmm0
    vcvtps2pd  %xmm0, %xmm0
    ret                                  ; Return f



参考书籍:《深入理解计算机系统》第三章——程序的机器级表示。
  • 大小: 114.9 KB
  • 大小: 103.2 KB
分享到:
评论

相关推荐

    IEEE浮点数转换工具

    标题中的“IEEE浮点数转换工具”是指一个软件应用程序,其主要功能是将各种数据类型转换成符合IEEE 754标准的浮点数表示。 IEEE 754是计算机科学中广泛采用的一个标准,定义了如何用二进制表示浮点数,包括单精度...

    S7-200SMART 64位浮点数转换为32位浮点数指令库文件Double_to_Float.rar

    S7-200SMART 64位浮点数转换为32位浮点数指令库文件Double_to_Float

    HEX与浮点数相互转换

    描述中提到的“支持浮点数与HEX格式相互转换”,意味着存在一个工具或者编程函数,能够将浮点数转换为HEX字符串,反之亦然。这个过程涉及到以下几个步骤: 1. **浮点数到HEX**: 首先,浮点数按照IEEE 754标准转换为...

    S7-200SMART_双精度浮点数转换为单精度浮点数库文件及使用说明.rar

    在处理大量数据或资源有限的设备(如S7-200SMART)时,可能需要将双精度浮点数转换为单精度浮点数来节省空间。 2. **S7-200SMART的浮点数处理**: 虽然S7-200SMART支持浮点数运算,但其硬件并不直接支持双精度...

    三菱PLC浮点数运算指令

    - 在进行浮点数运算时,要注意数据类型的转换,确保所有的运算都是在浮点数之间进行,以避免精度损失或者运算错误。 在实际的工业控制项目中,PLC的浮点数运算指令是实现复杂控制逻辑的基础,例如PID控制、温度压力...

    64位浮点数与32位整数或32位浮点数之间的相互转换(V17版本仅限1500系列PLC使用).zip

    例如,可以使用“CONV”指令将64位浮点数转换为32位整数或32位浮点数,反之亦然。在转换过程中,需要注意精度损失和溢出问题。从64位浮点数转为32位整数时,超出32位整数范围的数值可能会导致信息丢失;而从32位整数...

    读写PLC浮点数+转换_MXComponentlabview_

    在LabVIEW中,可以使用内置的浮点数转换函数,如`Float32 To Integer`和`Integer To Float32`,分别对应于上述两个VI的功能。这两个函数确保了数据在PLC和LabVIEW之间正确无误地传递。 在实际应用中,你可能需要...

    AB-Micro系列PLC双精度浮点数转换为整形.pdf

    根据给定的文件信息,本知识点讲解将围绕AB-Micro系列PLC中如何将双精度浮点数转换为整形数进行展开,以下是详细知识点: 1. PLC在工业中的应用 PLC(可编程逻辑控制器)是工业自动化控制的核心设备之一。在物联网...

    S7-200PLC双精度浮点数转换为整形.pdf

    3. 双精度浮点数转换为整形算法:文档介绍了一种在S7-200 PLC中实现双精度数据无损转换的方法。该算法能够将双精度浮点数转换为整形数,确保了数据的准确性和管理的便利性。 4. 双精度转换算法的具体实现:通过特定...

    浮点数转十六进制转换器

    浮点数转十六进制转换器是一款专门设计用于将浮点数转换成十六进制表示的工具,它支持32位(单精度)和64位(双精度)的浮点数转换。浮点数在计算机系统中广泛使用,它们能够表示带有小数部分的数值,而十六进制是...

    S7-200SMART 64位浮点数转32位浮点数(源文件+库文件+程序注释).rar

    在处理数值计算时,有时我们需要将不同精度的浮点数进行转换,如将64位浮点数转换为32位浮点数。这个过程涉及到浮点数的表示方式、数据类型的转换以及可能的精度损失问题。 64位浮点数,也称为双精度浮点数(Double...

    显控PLC上位软件编程浮点数运算指令说明

    需要注意的是,进行浮点数运算时,要确保参与运算的操作数类型与指令要求相匹配,否则可能会产生错误的结果。 在编程时,还需要了解一些特定于显控PLC的编程规则和操作数描述。例如,操作数类型可能包括布尔型...

    浮点数转换工具 十六进制浮点数 与 十进制小数 相互转化查询

    浮点数转换是计算机科学中的一个重要概念,尤其是在编程和数据处理中。这个工具专注于十六进制浮点数和十进制小数之间的相互转化,它为程序员和计算爱好者提供了便捷的查询服务。以下是对这个工具及其相关知识点的...

    TIA博途中字符串转换相关指令的使用方法(一).docx

    TIA 博途中字符串转换相关指令的使用方法是指在 Siemens SIMATIC TIA Portal 中使用的字符串转换相关指令,包括移动和转换字符串指令、字符串和数值相互进行转换指令等。 1. 移动和转换字符串指令 移动和转换字符...

    MCS51浮点计算程序.zip_51 浮点_51单片机_浮点_浮点数_浮点数转换

    浮点数转换子程序的目标是将IEEE 754格式的浮点数转换为51单片机能理解和处理的格式,以及反之。转换过程涉及解码浮点数的各个部分,如确定符号、指数和尾数,并根据51单片机的内存结构和指令集重新编码。这个过程...

    显控PLC转换指令说明.pdf

    显控PLC转换指令是指在可编程逻辑控制器(PLC)编程中,用于不同数据类型之间转换的指令集合。这些转换指令对于数据的处理和算法的实现具有重要意义。根据提供的文件内容,下面将详细解释标题和描述中所提及的转换...

    十进制与浮点数相互转化工具.rar

    浮点数是一种用于近似表示实数的数据类型,它在计算机内部采用特定的二进制格式,即IEEE 754标准。本文将深入探讨十进制与浮点数之间的转化,以及在MIPS架构中如何实现这种转化。 首先,我们要理解浮点数的内部表示...

    S7-200SMART中如何把1个INT整型数据转换成REAL浮点型数据?.docx

    这个过程是为了准备接下来的浮点数转换,因为S7-200SMART不直接支持从INT到REAL的直接转换。假设我们有一个INT变量存储在VW200中,数值为123,我们可以通过`I-DI`指令将其转换为双精度整数并存储在VD204中。在这个...

    TIA博途中使用AT指令实现双字中高低字转换的具体方法示例.docx

    在TIA博途中,有时我们需要处理双字(DWORD)数据类型,尤其在与不同系统进行通信时,由于大端存储和小端存储模式的差异,可能需要对数据进行高低字转换。本示例详细讲解了如何使用AT指令在TIA博途中实现这一转换。 ...

Global site tag (gtag.js) - Google Analytics