我知道在Java中通过Math.log计数日志很容易 但是如何工作,因为在汇编中没有这样的就绪功能?
答案 0 :(得分:1)
要轻松计算对数,请使用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]