Assembly 使用NASM';s____;浮点?__;宏
NASM手册谈到了这些宏,但就我所见,它并没有真正解释如何使用它们。国家: 浮点常量仅可作为Assembly 使用NASM';s____;浮点?__;宏,assembly,x86-64,nasm,Assembly,X86 64,Nasm,NASM手册谈到了这些宏,但就我所见,它并没有真正解释如何使用它们。国家: 浮点常量仅可作为DB,DW,DD,DQ,DT,和DO,或作为特殊运算符\uuuuu8?\uuuuu8?,\uu16?\uuuuuu16?,\uuuu32?>23,以获取要用于某些内容的浮点常量的指数(和符号位) 记录在案: mov eax, __?float32?__(1.23) mov eax, __?float32?__(1.0) >> 23 mov dword [rdi], __?float32?__
DB
,DW
,DD
,DQ
,DT
,和DO
,或作为特殊运算符\uuuuu8?\uuuuu8?
,\uu16?\uuuuuu16?,\uuuu32?,\uuuuuuu80m?\uuuuuu
,\uuuu80e?\uuuuu
,\uuuuuuuu128l?\uuuuuu
和\uuuuuuuu128h?\uuuuuuuu
起初,我认为这是在数据部分之外使用浮点常量。但是当我尝试movxmm0、\uuuuu32?\uuuuu1.23)
时,我得到了一个“操作码和操作数的组合无效”错误。最后,我看到foo:dd\uuuuuu32?\uuuuuu(1.23)
起作用了。但我觉得这很奇怪;如果您可以直接执行dd 1.23
,这些宏有什么意义?一种可能是,例如,您可能需要在四字中定义一个精度浮点。这真的是这些宏的唯一用途,还是我用错了?这些宏不会改变x86没有直接源指令和XMM或x87目标指令的事实。记住,NASM是汇编程序,不是编译器
用例包括一种罕见的情况,即您希望将FP位模式立即移动到整数寄存器中,如mov eax、\uuuuuuu32?\uuuuuu1.23)
。之后,您可能会执行movd xmm0、eax
,甚至AVX-512vp广播xmm0、eax
通常编译器从内存中的常量将FP数据加载到寄存器中(这通常是一个不错的选择),但这不是唯一的方法
(AVX-512由于高效的广播,使即时更具吸引力,但您也可以仅使用AVX1或SSE3movddup
从内存广播双精度。编译器仍然使用内存常量进行标量浮点运算,这通常仍然是我的建议,除非分析显示在这方面存在大量数据缓存未命中,而不是大量I-通常在程序中缓存未命中。)
或者对于类似于的东西,如果(x)*fp_ptr=1.0;
,您可能希望立即移动到内存,如mov dword[rdi]、\uuuuu32?\uuuuu1.0)
另一个用例可能是在一个或一些其他情况下,您希望FP位模式作为一个不是dd
的整数值。尽管没有任何合理的想法
或者作为表达式的一部分,如\uuuuuuu32?\uuuuu(1.0)>>23
,以获取要用于某些内容的浮点常量的指数(和符号位)
记录在案:
mov eax, __?float32?__(1.23)
mov eax, __?float32?__(1.0) >> 23
mov dword [rdi], __?float32?__(1.0)
使用nasm-felf64 foo.asm组装,使用objdump-drwC-Mintel foo.o拆解
0: b8 a4 70 9d 3f mov eax,0x3f9d70a4
5: b8 7f 00 00 00 mov eax,0x7f
a: c7 07 00 00 80 3f mov DWORD PTR [rdi],0x3f800000
啊,是的,我刚刚用eax
试过,效果很好。事后看来,我没有试过,真是太蠢了……我还没意识到你根本无法将文本放入xmm
寄存器(我正在试着学习向量和SIMD)。不管怎样,你已经给了我我一直在寻找的答案。@mediocrevegetable1:还要记住,mov
永远不会有XMM目的地(),所以这是下次指令无法汇编时要检查的另一件事。可以编写XMM寄存器的指令包括movd XMM,r/m32
,movdqu XMM,XMM/mem
,vbroadcastss XMM,XMM/mem
啊,好的,我还没有意识到。我会查找这些指令,谢谢链接。@mediocrevegetable1:Updated我的答案是另一个似是而非且可能有趣的用例:mov立即进入内存,或在浮点32位模式上进一步进行常量表达式计算。感谢更新。我没有想过使用它们,特别是在位移位的情况下。有趣。