- 浏览: 142349 次
文章分类
最新评论
在浮点寄存器概述一节中对浮点寄存器和浮点传送指令进行了相关介绍,这里将继续给出浮点数和整数数据类型之间以及不同浮点格式之间进行转换的指令集合,它们都是对单个数据值进行操作的标量指令。
首先来看一下将浮点数转换成整数的指令。
这些指令把一个从 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 函数为例。
则 GCC 生成的 x86-64 汇编代码类似如下。
参考书籍:《深入理解计算机系统》第三章——程序的机器级表示。
首先来看一下将浮点数转换成整数的指令。
这些指令把一个从 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
参考书籍:《深入理解计算机系统》第三章——程序的机器级表示。
发表评论
-
浮点运算指令
2019-05-22 23:13 1575上一节介绍了浮点数与各种数值类型之间的相互转换 ... -
浮点寄存器概述
2019-05-14 22:31 2589本文介绍的浮点寄存器是基于 AVX2(Adva ... -
汇编指令之跳转指令
2019-04-15 00:21 4798正常执行的情况下,指令会按照顺序一条条地执行, ... -
汇编指令之条件码
2019-04-08 21:05 2359在系统底层,除了整数寄存器,CPU 还维护着一 ... -
汇编指令之算术和逻辑操作指令
2019-03-28 22:16 1382下表是 x86-64 ... -
汇编指令之数据传送指令
2019-03-25 21:28 1288在x86-64 中的 ... -
x86-64 中的寄存器与汇编操作数杂述
2019-03-20 21:45 993Intel 中常用 ... -
hello 程序执行背后的故事
2018-12-26 21:48 608源文件 hello. ... -
linux启动服务概述
2017-04-08 02:43 398传统的linux中定义了七个运行级,分别如下: ... -
unix限制
2017-04-04 16:08 578UNIX系统实现定义了很多幻数和常量,其中有很 ... -
linux引导加载程序--GRUB
2017-04-04 04:22 625linux世界里有两种 ... -
存储器映射
2016-06-13 00:12 553注:本文摘自《深入理解计算机操作系统》第九章--虚拟存 ... -
虚拟存储器对存储器管理的作用
2016-06-10 16:00 695注:本文中的大部分内容均是摘录自《深入理解计算机系统》一书,权 ... -
信号处理问题
2016-06-03 08:31 561注:本文摘自《深入理解计算机系统》第8章 --- 异常控制流。 ... -
僵尸进程
2016-05-23 23:57 361在解释僵尸进程的概念之前,我们得先了解这样的一个事实: 一个进 ... -
程序优化之存储器别名使用
2016-05-20 08:55 797说明:本文示例摘自《深入理解计算机系统》第五章----优化程序 ... -
条件变量基本概念与原理(转载)
2016-05-20 08:54 1579对于条件变量,我一直感到很困惑,搞不清其与互斥锁到底有啥区别, ... -
CPU与磁盘的交互过程
2016-05-19 09:05 1839对于计算机系统底层技术,想必很多人都和我一样不太了解,最近在学 ... -
存储器层次结构中基本的缓存原理
2016-05-19 09:00 668对于操作系统,我们知道,越靠近CPU的存储器,其存储速度就会越 ... -
异常处理
2016-05-19 00:29 424我知道很多人都知道异常处理,但可能对其底层并不太了解,现在我们 ...
相关推荐
S7-200SMART 64位浮点数转换为32位浮点数指令库文件Double_to_Float
标题中的“IEEE浮点数转换工具”是指一个软件应用程序,其主要功能是将各种数据类型转换成符合IEEE 754标准的浮点数表示。 IEEE 754是计算机科学中广泛采用的一个标准,定义了如何用二进制表示浮点数,包括单精度...
例如,可以使用“CONV”指令将64位浮点数转换为32位整数或32位浮点数,反之亦然。在转换过程中,需要注意精度损失和溢出问题。从64位浮点数转为32位整数时,超出32位整数范围的数值可能会导致信息丢失;而从32位整数...
在处理大量数据或资源有限的设备(如S7-200SMART)时,可能需要将双精度浮点数转换为单精度浮点数来节省空间。 2. **S7-200SMART的浮点数处理**: 虽然S7-200SMART支持浮点数运算,但其硬件并不直接支持双精度...
描述中提到的“支持浮点数与HEX格式相互转换”,意味着存在一个工具或者编程函数,能够将浮点数转换为HEX字符串,反之亦然。这个过程涉及到以下几个步骤: 1. **浮点数到HEX**: 首先,浮点数按照IEEE 754标准转换为...
- 在进行浮点数运算时,要注意数据类型的转换,确保所有的运算都是在浮点数之间进行,以避免精度损失或者运算错误。 在实际的工业控制项目中,PLC的浮点数运算指令是实现复杂控制逻辑的基础,例如PID控制、温度压力...
根据给定的文件信息,本知识点讲解将围绕AB-Micro系列PLC中如何将双精度浮点数转换为整形数进行展开,以下是详细知识点: 1. PLC在工业中的应用 PLC(可编程逻辑控制器)是工业自动化控制的核心设备之一。在物联网...
在LabVIEW中,可以使用内置的浮点数转换函数,如`Float32 To Integer`和`Integer To Float32`,分别对应于上述两个VI的功能。这两个函数确保了数据在PLC和LabVIEW之间正确无误地传递。 在实际应用中,你可能需要...
3. 双精度浮点数转换为整形算法:文档介绍了一种在S7-200 PLC中实现双精度数据无损转换的方法。该算法能够将双精度浮点数转换为整形数,确保了数据的准确性和管理的便利性。 4. 双精度转换算法的具体实现:通过特定...
浮点数转十六进制转换器是一款专门设计用于将浮点数转换成十六进制表示的工具,它支持32位(单精度)和64位(双精度)的浮点数转换。浮点数在计算机系统中广泛使用,它们能够表示带有小数部分的数值,而十六进制是...
将一个浮点数转换成32位浮点数的存储形式,可以依据其数值计算对应的指数和尾数。计算时,将指数调整为二进制表示,并减去偏移量127得到指数部分,然后将小数部分转换为二进制,以1开头,后面跟随23位小数的二进制...
需要注意的是,进行浮点数运算时,要确保参与运算的操作数类型与指令要求相匹配,否则可能会产生错误的结果。 在编程时,还需要了解一些特定于显控PLC的编程规则和操作数描述。例如,操作数类型可能包括布尔型...
在处理数值计算时,有时我们需要将不同精度的浮点数进行转换,如将64位浮点数转换为32位浮点数。这个过程涉及到浮点数的表示方式、数据类型的转换以及可能的精度损失问题。 64位浮点数,也称为双精度浮点数(Double...
浮点数转换是计算机科学中的一个重要概念,尤其是在编程和数据处理中。这个工具专注于十六进制浮点数和十进制小数之间的相互转化,它为程序员和计算爱好者提供了便捷的查询服务。以下是对这个工具及其相关知识点的...
TIA 博途中字符串转换相关指令的使用方法是指在 Siemens SIMATIC TIA Portal 中使用的字符串转换相关指令,包括移动和转换字符串指令、字符串和数值相互进行转换指令等。 1. 移动和转换字符串指令 移动和转换字符...
浮点数转换子程序的目标是将IEEE 754格式的浮点数转换为51单片机能理解和处理的格式,以及反之。转换过程涉及解码浮点数的各个部分,如确定符号、指数和尾数,并根据51单片机的内存结构和指令集重新编码。这个过程...
浮点数是一种用于近似表示实数的数据类型,它在计算机内部采用特定的二进制格式,即IEEE 754标准。本文将深入探讨十进制与浮点数之间的转化,以及在MIPS架构中如何实现这种转化。 首先,我们要理解浮点数的内部表示...
显控PLC转换指令是指在可编程逻辑控制器(PLC)编程中,用于不同数据类型之间转换的指令集合。这些转换指令对于数据的处理和算法的实现具有重要意义。根据提供的文件内容,下面将详细解释标题和描述中所提及的转换...
这个过程是为了准备接下来的浮点数转换,因为S7-200SMART不直接支持从INT到REAL的直接转换。假设我们有一个INT变量存储在VW200中,数值为123,我们可以通过`I-DI`指令将其转换为双精度整数并存储在VD204中。在这个...