Assembly 如何计算masm程序集中的日志和项次?
我知道在java中,通过Math.log计算日志是很容易的Assembly 如何计算masm程序集中的日志和项次?,assembly,masm,logarithm,Assembly,Masm,Logarithm,我知道在java中,通过Math.log计算日志是很容易的 但是,既然在汇编中没有这样的就绪函数,它是如何工作的呢?要轻松计算对数,请使用x87 FPU的FYL2X指令。此指令计算st1*log2(st0),然后弹出寄存器堆栈。因为这是一个双对数,所以需要先推一个合适的转换因子。幸运的是,FPU的ROM中内置了合适的转换系数,可通过特殊说明访问: num real8 1.234 ; the datum you want to convert out real8
但是,既然在汇编中没有这样的就绪函数,它是如何工作的呢?要轻松计算对数,请使用x87 FPU的
FYL2X
指令。此指令计算st1*log2(st0)
,然后弹出寄存器堆栈。因为这是一个双对数,所以需要先推一个合适的转换因子。幸运的是,FPU的ROM中内置了合适的转换系数,可通过特殊说明访问:
num real8 1.234 ; the datum you want to convert
out real8 ? ; the memory location where you want to place the result
...
; dual logarithm (base 2)
fld1 ; st: 1
fld num ; st: 1 num
fyl2x ; st: log2(num)
fstp out ; store to out and pop
; decadic logarithm (base 10)
fldl2t ; st: log2(10)
fld num ; st: log2(10) num
fyl2x ; st: log10(num)
fstp out ; store to out and pop
; natural logarithm (base e)
fldl2e ; st: log2(e)
fld num ; st: log2(e) num
fyl2x ; st: ln(num)
fstp out ; store to out and pop
请注意,SSE或AVX没有类似的说明;如果不想使用x87 FPU,则必须通过数值近似手动计算对数。这通常比直接使用fyl2x
更快
可以在使用SSE进行浮点运算的程序中使用此代码;只需将数据移动到x87 FPU即可计算对数。由于无法直接从SSE寄存器移动到x87 FPU,因此必须遍历堆栈:
sub rsp, 8 ; allocate stack space
; SSE -> x87
movsd real8 ptr [rsp], xmm0
fld real8 ptr [rsp]
; x87 -> SSE with pop
fstp real8 ptr [rsp] ; store and pop
movsd xmm0, real8 ptr [rsp]
; x87 -> SSE without pop
fst real8 ptr [rsp] ; just store
movsd xmm0, real8 ptr [rsp]
实际上有
FYL2X
,但那是x87。你能更清楚地说明你想要什么类型的东西吗?你是在32位模式下编程还是在64位模式下编程?您想要一个简单的解决方案还是一个快速的解决方案?64,简单的解决方案请参阅如何有效地执行。SSE2版本(对于x86-64)应该很容易。(查看编译器输出以从C内部函数获取asm)。另请参阅,以获取简化的/slowfyl2x
版本。此版本的可能副本几乎与的副本相同,但您添加了不同的日志基础。@PeterCordes说实话,我不知道副本。