1

アセンブリで対数関数をプログラムしようとしています。この関数は、基数 (32 ビット整数) と値 x (64 ビット浮動小数点) の 2 つの引数を取ります。

私が現在これを行う必要があるアイデアは、対数の性質を使用して FYL2X と FDIVP を使用することです。

log (base a) b = (log (base 10) b / log (base 10) a) なので、対数関数を実装できると思います。XMMが使えないので、FPUのレジスタにどのように設定すればよいですか?

4

3 に答える 3

1

FDIVP は で除算st(0)st(1)ます。つまり、最初に除数をロードし、次に対数を計算し、FDIVP でファイナライズする必要があります。

OTOH、関数FYL2Xは ST(1) = ST(1) * Log2(ST(0)) です。続いて pop st(0);

したがって、log2(base) の逆数を計算し、それを FYL2X の乗数として使用できます。
さらに、これらの値のいくつかを表にして、次のようなものを使用することはおそらく理にかなっています。

  shl bx, 3
  fld inv_log_base[bx]
  fld argument
  fyl2x
于 2013-04-25T15:12:05.307 に答える
1

bsrしたがって、2 進整数の log2 を ( で) 計算し、FPU を介してそれを 10 進数に変換するコメント付きの例を次に示します。コードは x86 (i386) ですが、x86-64 (amd64) に簡単に変換できます。

最も厄介な部分は、CW (FPU コントロール ワード) の操作に関するものです。それを除いて、「私のレジスタはスタックとして使用される」ことに慣れていれば、多かれ少なかれ自明です。

    .text
    .globl  main
    .type   main, @function
main:
    movl    $1024, %eax ;; pushing the integer (1024) to analyze
    bsrl    %eax, %eax  ;; bit scan reverse (give the smallest non zero index)
    inc     %eax        ;; taking the 0th index into account

    pushl   %eax        ;; saving the previous result on the stack

    fildl   (%esp)      ;; loading the previous result to the FPU stack (st(0))
    fldlg2              ;; loading log10(2) on the FPU stack
    fmulp   %st, %st(1) ;; multiplying %st(0) and %st(1) and storing result in %st(0)

    ;; We need to set the FPU control word to 'round-up' 
    ;; (and not 'round-down' which is the default)
    fstcw  -2(%esp)      ;; saving the old FPU control word
    movw   -2(%esp), %ax ;; storing the FPU control word in %ax
    andw   $0xf3ff, %ax  ;; removing everything else
    orw    $0x0800, %ax  ;; setting the proper bit to '1'
    movw   %ax, -4(%esp) ;; getting the value back to memory
    fldcw  -4(%esp)      ;; setting the FPU control word to the proper value

    frndint              ;; rounding-up st(0)

    fldcw  -2(%esp)      ;; restoring the original FPU control word

    fistpl (%esp)        ;; loading the final result to the stack
    popl   %eax          ;; setting the return value to be our result

    leave
    ret

この助けを願っています。

于 2013-04-25T06:39:26.823 に答える
1

FPU命令とレジスタを使用するだけで、XMM命令とレジスタはそれらとは何の関係もありません。

FLDおよび命令を使用して、FILD浮動小数点値と整数値を FPU レジスタ スタックにロードします。

CPU リファレンスがない場合は、今すぐ intel.com にアクセスしてダウンロードしてください。無料で。

于 2013-04-25T05:00:32.717 に答える