⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 浮点指令.htm

📁 ARM指令集
💻 HTM
📖 第 1 页 / 共 2 页
字号:
    <TD>存储浮点值 
  <TR>
    <TD><A 
      href="http://www.linuxforum.net/books/mhss/arm/fpops.html#binop">SUF</A> 
    <TD>减法 
  <TR>
    <TD><A 
      href="http://www.linuxforum.net/books/mhss/arm/fpops.html#unop">TAN</A> 
    <TD>正切 
  <TR>
    <TD><A 
      href="http://www.linuxforum.net/books/mhss/arm/fpops.html#unop">URD</A> 
    <TD>非规格化舍入 
  <TR>
    <TD><A 
      href="http://www.linuxforum.net/books/mhss/arm/fpops.html#wfc">WFC</A> 
    <TD>写 FP 控制寄存器 
  <TR>
    <TD><A 
      href="http://www.linuxforum.net/books/mhss/arm/fpops.html#wfs">WFS</A> 
    <TD>写 FP 状态寄存器 </TR></TBODY></TABLE>
<P>  
<P>本文档部分内容取自 ARM 汇编器手册。</P>
<P>ARM 可以与最多 16 个协处理器相接口(interface)。ARM3 和以后的处理器在 ARM 
内有虚拟的协处理器来处理内部控制功能。而可获得的第一个协处理器是浮点处理器。这个芯片处理 IEEE 标准的浮点运算。定义了一个标准的 ARM 
浮点指令集,所以编码可以跨越所有 RISC OS 
机器。如果不存在实际的硬件,则这些指令被截获并由浮点模拟器模块(FPEmulator)来执行。程序不需要知道是否存在 FP 
协处理器。唯一不同的是执行速度。</P>
<P>RISC OS 的 BASIC 
汇编器,作为标准,不支持任何真实的浮点指令。你可以转换整数到你的实现定义的‘浮点’并用它们进行(最普通的定点)基本数学运算,但你不能与浮点协处理器交互并以‘固有的’方式来做这些事情。但是,扩展汇编器功能的补丁中包含了 
FP 指令。 
<P>ARM IEEE FP 系统由 8 个高精度 FP 寄存器(F0 到 
F7)。寄存器的格式是无关紧要的,因为你不能直接访问这些寄存器,寄存器只在它被传送到内存或 ARM 寄存器时是‘可见的’。在内存中,一个 FP 
寄存器占用三个字,但因为 FP 系统把它重新装载到自己的寄存器中,这三个字的格式是无关紧要的。还有一个 FPSR (浮点状态寄存器),它类似于 ARM 自己的 
PSR,持有应用程序可能需要的状态信息。可获得的每个标志都有一个‘陷阱’,这允许应用程序来启用或禁用与给定错误关联的陷阱。FPSR 还允许你得知在 FP 
系统得不同实现之间的区别。还有一个 FPCR (浮点控制寄存器)。它持有应用程序不应该访问的信息,比如开启和关闭 FP 单元的标志。典型的,硬件有 FPCR 
而软件没有。 
<P>FP 单元可以软件实现比如 FPEmulator 模块,硬件实现比如 FP 芯片(和支持代码),或二者的组合。二者的最好的例子是 Warm Silence 
Software 补丁,它允许 ARM FP 操作利用配备在 PC 协处理器卡上的 80x87 作为作为一个浮点协处理器。 
<P>计算的结果如同有无限的精度,接着被舍入成要求的精度。舍入方式有就近舍入,向正无穷(P)舍入, 向负无穷舍入(M), 
或向零舍入。缺省的是就近舍入。如果不可抉择,则舍入到最近似的偶数。工作精度是 80 位,其组成是 64 位尾数,15 
位指数,和一个符号位。在一些实现中对用单精度工作的指令提供了更好的性能 - 特别是完全基于软件的那些实现。 
<P>FPSR 包含 FP 系统所需的状态。总是提供 IEEE 标志,但只在一次 FP 比较操作之后才可获得结果标志。 
<P>浮点指令不应该用在 SVC 模式下。 
<P>FPSR 的低字节是例外标志字节。 <PRE>        6          4      3      2      1      0
FPSR:   保留       INX    UFL    OFL    DVZ    IVO
</PRE>当引发一个例外条件的时候,把在位 0 到 4 中的适当的累计(cumulative)例外标志设置为 
1。如果设置了相关的陷阱位,则按操作系统指定的方式把一个例外递送给用户程序。(注意在下溢的情况下,陷阱启用位的状态决定在什么条件下设置下溢标志。) 只能用 
WFS 指令清除这些标志。 
<P><CODE>IVO - invalid operation 无效操作</CODE><BR>在进行的操作的一个操作数是无效时设置 IVO。无效操作有: 
<UL>
  <LI>在一个捕获(trapping)的 NaN (not-a-number:非数)上进行任何操作。 
  <LI>无穷大幅值(magnitude)相减,例如 (+∞) + (-∞)。 
  <LI>乘法 0 * ∞。 
  <LI>除法 ∞/∞ 或 x/0。 
  <LI>x REM y 这里 x = ∞ 或 y = 0。<BR>(REM 是浮点除法操作的余数。) 
  <LI>任何小于 0 的数的平方根。 
  <LI>在上溢或操作数是 NaN 
  的时候进行转换成整数或十进制数。<BR>如果上溢使转换不可能,则生成最大的正或负整数(依赖于操作数的符号)并通知(signal)一个 IVO。 
  <LI>比较时有未对阶(Unordered)操作数例外。 
  <LI>ACS、ASN、SIN、COS、TAN、LOG、LGN、POW、或 RPW 有无效/错误的参数。 </LI></UL>
<P><CODE>DVZ - division by zero 除零</CODE><BR>如果除数是零而被除数是一个有限的、非零的数则设置 DVZ 
标志。如果禁用了陷阱则返回一个正确的有符号的无穷。还为 LOG(0) 和 LGN(0) 设置这个标志。如果禁用了陷阱则返回负无穷。 
<P><CODE>OFL - overflow 上溢</CODE><BR>结果幅值超出目的格式最大的数的时候设置 OFL 
标志,舍入的结果是指数范围无限大的(unbounded)。 
因为在结果被舍入之后检测上溢,在一些操作之后是否发生上溢依赖于舍入模式。如果禁用了陷阱,要么返回一个有正确符号的无穷,要么返回这个格式的最大的有限数。这依赖于舍入模式和使用的浮点系统。 

<P><CODE>UFL - underflow 下溢</CODE><BR>两个有关联的事件产生下溢: 
<UL>
  <LI>极小值(tininess) -&nbsp; 微小的非零结果在幅值上小于这个格式的最小规格化数。 
  <LI>准确性损失 - 反规格化导致的准确性损失可能大于单独舍入导致的准确性损失。 </LI></UL>依赖于 UFL 陷阱启用位的值,以不同的方式设置 UFL 
标志。如果启用了陷阱,则不管是否有准确性损失极,在检测到极小值时就设置 UFL 标志。如果禁用了陷阱,则在检测到极小值和准确性损失二者时设置 UFL 
标志(在这种情况下还设置 INX 标志);否则返回一个有正确符号的零。因为在结果被舍入之后检测下溢,在一些操作之后是否发生下溢依赖于舍入模式。 
<P><CODE>INX - inexact 不精确</CODE><BR>如果操作的舍入的结果是不精确的(不同于可用无穷精度计算的值),或者在禁用 OFL 
陷阱时发生上溢,或者在禁用 UFL 陷阱时发生了下溢,则设置 INX 标志。OFL 或 UFL 陷阱优先于 INX。在计算 SIN 或 COS 的时候也设置 
INX 标志,但 SIN(0) 和 COS(1) 例外。老的 FPE 和 FPPC 系统在处理 INX 标志上可能不同。由于这个不一致性,我建议你不要启用 
INX 陷阱。 
<P>&nbsp;精度: 
<UL>
  <LI><CODE>S&nbsp; -</CODE> 单精度 
  <LI><CODE>D&nbsp; -</CODE> 双精度 
  <LI><CODE>E&nbsp; -</CODE> 双扩展精度 
  <LI><CODE>P&nbsp; -</CODE> 压缩(packed)十进制数 
  <LI><CODE>EP -</CODE> 扩展压缩十进制数 </LI></UL>
<P>&nbsp;舍入模式: 
<UL>
  <LI><CODE>&nbsp;&nbsp; -</CODE> 最近(不需要字符) 
  <LI><CODE>P&nbsp; -</CODE> 正无穷 
  <LI><CODE>M&nbsp; -</CODE> 负无穷 
  <LI><CODE>Z&nbsp; -</CODE> 零 </LI></UL>
<P><A name=ldf></A><BR><CODE>LDF{条件}&lt;精度&gt;&nbsp; &lt;fp 寄存器&gt;, 
&lt;地址&gt;</CODE><BR>装载浮点值。<BR>地址可以是下列形式: 
<UL>
  <LI>[Rn] 
  <LI>[Rn], #offset 
  <LI>[Rn, #offset] 
  <LI>[Rn, #offset]! </LI></UL>这个调用类似于 LDR。<BR>你的汇编器可能允许使用如下文字:LDFS F0, [浮点值] 
<P><A name=stf></A><BR><CODE>STF{条件}&lt;精度&gt;&nbsp; &lt;fp 寄存器&gt;, 
&lt;地址&gt;</CODE><BR>存储浮点值。<BR>地址可以是下列形式: 
<UL>
  <LI>[Rn] 
  <LI>[Rn], #offset 
  <LI>[Rn, #offset] 
  <LI>[Rn, #offset]! </LI></UL>这个调用类似于 STR。<BR>你的汇编器可能允许使用如下文字:STFED F0, [浮点值] 
<P><A name=lfm></A><A name=sfm></A><BR><CODE>LFM</CODE> and 
<CODE>SFM</CODE><BR>它们类似于 LDM 和 STM,但因为一些版本的 FPEmulator 不支持它们就不进行描述了。最新版本的 RISC 
OS 3.1x (2.87) 中的 FP 模块支持。如果你想让你的软件只在支持 SFM 的系统上操作就使用它吧。否则你需要用 STF 
的一个序列来‘伪造’它。LFM/LDF 也是类似。 
<P><A name=flt></A><BR><CODE>FLT{条件}&lt;精度&gt;{舍入}&nbsp; &lt;fp 寄存器&gt;, 
&lt;寄存器&gt;<BR>FLT{条件}&lt;精度&gt;{舍入}&nbsp; &lt;fp 寄存器&gt;, 
#&lt;值&gt;</CODE><BR>转换整数成浮点数,要么从一个 ARM 寄存器要么从一个绝对值。 
<P><A name=fix></A><BR><CODE>FIX{条件}{舍入}&nbsp; &lt;寄存器&gt;, &lt;fp 
寄存器&gt;</CODE><BR>转换浮点数成整数。 
<P><A name=wfs></A><BR><CODE>WFS{条件}&nbsp; &lt;寄存器&gt;</CODE><BR>用指定 ARM 
寄存器的内容写浮点状态寄存器。 
<P><A name=rfs></A><BR><CODE>RFS{条件}&nbsp; &lt;寄存器&gt;</CODE><BR>读浮点状态寄存器到指定的 
ARM 寄存器中。 
<P><A name=wfc></A><BR><CODE>WFC{条件}&nbsp; &lt;寄存器&gt;</CODE><BR>用指定 ARM 
寄存器的内容写浮点控制寄存器。<BR>专属超级用户模式,并只存在于支持它的硬件上。 
<P><A name=rfc></A><BR><CODE>RFC{条件}&nbsp; &lt;寄存器&gt;</CODE><BR>读浮点控制寄存器到指定的 
ARM 寄存器中。<BR>专属超级用户模式,并只存在于支持它的硬件上。 
<P>浮点协处理器数据操作指令的格式是: <PRE>双目操作{条件}&lt;精度&gt;{舍入}  &lt;目的浮点寄存器&gt;, &lt;源浮点寄存器&gt;, &lt;源浮点寄存器&gt;
双目操作{条件}&lt;精度&gt;{舍入}  &lt;目的浮点寄存器&gt;, &lt;源浮点寄存器&gt;, #&lt;值&gt;
单目操作{条件}&lt;精度&gt;{舍入}  &lt;目的浮点寄存器&gt;, &lt;源浮点寄存器&gt;
单目操作{条件}&lt;精度&gt;{舍入}  &lt;目的浮点寄存器&gt;, #&lt;值&gt;
 
&lt;值&gt;常量应当是 0、1、2、3、4、5、10、或 0.5。
</PRE>
<P><A name=binop></A><BR>双目操作有...<BR><CODE>ADF -</CODE> 加法<BR><CODE>DVF -</CODE> 
除法<BR><CODE>FDV -</CODE> 快速除法 - 只定义用单精度工作<BR><CODE>FML -</CODE> 快速乘法 - 
只定义用单精度工作<BR><CODE>FRD -</CODE> 快速反向除法 - 只定义用单精度工作<BR><CODE>MUF -</CODE> 
乘法<BR><CODE>POL -</CODE> 极化角<BR><CODE>POW -</CODE> 幂<BR><CODE>RDF -</CODE> 
反向除法<BR><CODE>RMF -</CODE> 余数<BR><CODE>RPW -</CODE> 反向幂<BR><CODE>RSF -</CODE> 
反向减法<BR><CODE>SUF -</CODE> 减法<BR>
<P><A name=unop></A><BR>单目操作有...<BR><CODE>ABS -</CODE> 绝对值<BR><CODE>ACS -</CODE> 
反余弦<BR><CODE>ASN -</CODE> 反正弦<BR><CODE>ATN -</CODE> 反正切<BR><CODE>COS -</CODE> 
余弦<BR><CODE>EXP -</CODE> 指数<BR><CODE>LOG -</CODE> 常用对数<BR><CODE>LGN -</CODE> 
自然对数<BR><CODE>MVF -</CODE> 传送<BR><CODE>MNF -</CODE> 传送取负的值<BR><CODE>NRM -</CODE> 
规格化<BR><CODE>RND -</CODE> 舍入到整数值<BR><CODE>SIN -</CODE> 正弦<BR><CODE>SQT -</CODE> 
平方根<BR><CODE>TAN -</CODE> 正切<BR><CODE>URD -</CODE> 非规格化舍入<BR>
<P><A name=cmf></A><BR><CODE>CMF{条件}&lt;精度&gt;{舍入}&nbsp; &lt;fp 寄存器1&gt;, &lt;fp 
寄存器2&gt;</CODE><BR>把 FP 寄存器 2 与 FP 寄存器 1 进行比较。<BR>变体 CMFE 比较带有例外。 
<P><A name=cnf></A><BR><CODE>CNF{条件}&lt;精度&gt;{舍入}&nbsp; &lt;fp 寄存器1&gt;, &lt;fp 
寄存器2&gt;</CODE><BR>把 FP 寄存器 2 与 FP 寄存器 1 取负的值进行比较。<BR>变体 CNFE 比较带有例外。 
<P>提供带例外和不带例外的比较,如果操作数是未对阶的(就是说它们中的一个或两个是非数)时可以引发这个例外。为了遵守 IEEE 754,CMF 
指令只应用于测试等同(就是说以后使用 BEQ 或 BNE) 或测试未对阶(在 V 标志中)。应当对所有其他测试使用 CMFE 指令(以后用 
BGT、BGE、BLT、BLE)。&nbsp; 
<P>当 FPSR 中的 AC 位清除了的时候,在比较之后,ARM 标志 N、Z、C、V 表示:<BR><CODE>N = 
</CODE>小于<BR><CODE>Z = </CODE>等于<BR><CODE>C = </CODE>大于等于<BR><CODE>V = 
</CODE>未对阶 
<P>当 FPSR 中的 AC 位设置了的时候,在比较之后,这些标志表示:<BR><CODE>N = </CODE>小于<BR><CODE>Z = 
</CODE>等于<BR><CODE>C = </CODE>大于等于或未对阶<BR><CODE>V = </CODE>未对阶&nbsp; 
<P>在使用 objasm 的 APCS 代码中,要存储一个浮点值,你可以使用宏指令(directive) DCF。对单精度添加‘S’,对双精度添加‘D’。 
<P>  
<HR SIZE=3>
<A href="http://www.linuxforum.net/books/mhss/arm/index.html">Return to 
assembler index</A> 
<HR SIZE=3>

<ADDRESS>Copyright &copy; 2000 Richard Murray </ADDRESS></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -