問題タブ [x87]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
assembly - x87 FPU での単精度浮動小数点数の単純な追加
2 つの単精度浮動小数点数を取り、それらを加算して結果を表示する小さなアセンブリ プログラムを作成しています。ただし、後で使用するために結果をレジスタに保存したいと思います。作業を開始するために、C++ プログラムをアセンブリ プログラムにコンパイルし、それを編集しようとしました。ただし、次のような結果が得られます。
まず、フロートに関しては、s
32ビットとl
64ビットを意味するのは正しいですか? 28(%esp)
次に、データ レジスタ スタックに格納するためだけに32 ビットの float 値を にポップするのはなぜですか? これらの 2 行を削除すると、結果の精度が低下します。これは奇妙です。最後に、データ レジスタ スタックを再度ポップしますが、今回は 64 ビット値です。単精度の 32 ビット値が必要です。ただし、に変更l
するとs
、0が得られます。正確に何が起こっているのか知っている人はいますか?
c++ - 古いコンパイラの ftol (float to long) 関数を C に移植する
私は、いくつかの計算を行い、 を に変換する古い実装に依存していfloat
ますint
。
ただし、計算を複製した後、丸め結果が異なるため、一部の値がずれています。
要するに、バイナリが afloat
をint
( long
) に変換するために次のコードを使用していることです。
これは、単に unsigned を実行する場合とは異なる動作をしint var = (unsigned int)floatVal;
ます。
これは古いftol
実装であり、 からfloat
への変換int
が非常に遅く、コンパイラが FPU 丸めモードを変更する必要があったために行われたと思います。
これと非常によく似ています http://www.libsdl.org/release/SDL-1.2.15/src/stdlib/SDL_stdlib.c
関数をCに変換するのを手伝ってくれる人はいますか? または、 Visual Studio を使用してfloat
パラメーターとリターンを使用してインライン ASM 関数を作成する方法を教えてください。int
の 1SDL_sdtlib.c
つにはヘッダーがなく、関数の引数なしで呼び出す方法がわかりません。
assembly - FPU Nasm x86 アセンブリで計算を行うときに -nan を取得する
まず第一に、これに返信してくれた人に感謝したいと思います。あなたの助けは大歓迎です!
コマンド ライン パラメータとしてプログラムに渡された一連の浮動小数点数の標準偏差を計算しようとしています。まず、各パラメーター文字列を変数に格納しtemp
、次に を使用してそれらを浮動小数点数に解析しますsscanf()
。私の最初の問題は、最初の(そして最初に言うとき、私は自分のプログラムの名前の後のものについて話しているので、実際には2番目の)コマンドラインパラメーターが解析されないことです。数値の平均を計算するために使用するループでは、各パラメーターを浮動小数点数に解析した直後に出力しようとします。最初のものを除くすべてを常に出力します。最初のものは常に として出力され-nan
ます。また、変数を変更したことはありませんが、変数も同様にstd_dev
出力されます。-nan
これは私を困惑させます。私は何を間違っていますか?
コードは次のとおりです。
再度、感謝します!
[編集: 標準偏差の実際の計算はまだ完了していません。私が持っているのは、平均を計算するループだけです。]
assembly - x87 FPU の精度について
Intel IA-32 ソフトウェア開発者マニュアル。x87 FPU制御ワードのビット8と9が浮動小数点計算の精度を決定すると言われています。デフォルトの精度は拡張倍精度です。命令「FINIT」の実行後、精度は倍精度浮動小数点に設定されます。問題は、「FINIT」が実行された後、x87 FPU が 80 ビット データ レジスタの 64 ビットのみを使用して計算することです。また、FPU は拡張倍精度浮動小数点値をメモリから (へ) 受け入れる (出力する) ことはできません。これは正しいですか?
assembly - 上記が機能する場合、アセンブラーはどのようにジャンプしますか
2 つの値を比較し
1
、pi
次に、「上にある場合はジャンプ」を使用するか、大きい場合はジャンプします。
我々は持っています:
ジャンプしないように。
条件が次の場合にのみ発生します。
x - value > 0
本当ですよね?オーバーフローフラグは jg でどのように機能しますか?
ジャンプしますか?
FPUの使用
assembly - アセンブラー テイラー シリーズ arctg x
C
プログラムから 2 つの変数のみを受け取り、最後に答えをプログラムに返すプログラムをアセンブリで作成しC
ました。アセンブリ ファイルの何が問題なのかを見つけるのに問題がありました。
私の目標は、FPU (nasm) を使用して、 をカウントするプログラムを作成することですarctg (x)
。ここで、はユーザーが入力しx
た の変数です。C
2 番目の変数は精度なので、テイラー級数の整数の数です。
プログラム C
:
プログラムassembler
:
プログラムを入力
accuracy > 2 (dokladnosc)
すると停止し、プログラムを入力すると1
リターン-x
ではなくx
私はnasmでこれらの行を使用してコンパイルします:(私はgccを使用しています)
結果としてST0をCに送信しようとします。それが私の目標です
linux - gcc 4.x は x87 FPU 演算をサポートしていませんか?
を使用してソースから gcc 4.x をコンパイルしようとしましたが--with-fpmath=387
、このエラーが発生しています: "Invalid --with-fpmath=387"
. 構成を調べたところ、このオプションがサポートされていないことがわかりました(ドキュメントではまだ可能なオプションとして言及されていますが):
基本的に、古いターゲットプラットフォーム用の実行可能ファイルを提供する必要があるため、このすべてを開始しました(実際、古いCeleronですが、DEFAULTによって libstdc++ によって明らかに使用されているSSE2命令はありません)。実行可能ファイルは、libstdc++ のルーチンのコピーから来る最初の命令 (movq XMM0,...) でクラッシュし、「不正な命令」メッセージが表示されます。これを解決する方法はありますか?既存のコード ベースを移植できるようにするには、かなり最近の g++ を使用する必要があります。
古いビルドからこれらのヘッダー/ソースを提供して、通常の x87 命令のサポートを有効にして、SSE 命令が参照されないようにすることは可能でしょうか?
更新: オブジェクト コードに SSE2 命令を含むコンパイル済みの libstdc++ について話していることに注意してください。したがって、問題は gcc コマンド ライン引数に関するものではありません。コードをコンパイルするときに gcc に何を提供していても、SSE2 命令が組み込まれている libstdc++ とリンクします。
本当の答えは、GCC をコンパイルするときに --with-fpmath スイッチを使用しないことです。configure スクリプトの switch ステートメントが sse または avx のみをサポートしていると考えて混乱しましたが、実際にはデフォルト値 (このスイッチには記載されていません) は「387」です。そのため、configure の実行時に --with-fpmath を使用しないようにしてください。それなしでGCCを再コンパイルしたところ、正常に動作するようになりました。
ありがとう。
assembly - Nasm fiadd 操作サイズが指定されていないエラー
nasm とFPU
x86 命令を使用します。FPU
st0
今、私が0にいるとしましょう.私は変数を持っています:
そして今操作:
動作しません、nasm のエラー:
いつ:
、結果 ( st0 = 0 の場合) は次のとおりです。
1
アセンブリコードではありません:
C コード:
私がジャンプする重要な行は27,28です:
それを修正する方法?
assembly - fstp コマンドの使用法
質問があります。浮動小数点ユニットのスタックが次のようになっているとしましょう。
この指示を実行した後:
私の予測では、ユニットは st(0) を st(1) に送信し (スタックの状況は になります1.5;1.5;2.5;0 etc
)、スタックの一番上をポップするので、状況は次のようになります。1.5;2.5;0 etc.
代わりに、次のように表示されます。
私の質問は、なぜst(7)
変化したのか、どうすれば期待した結果を達成できるのかということです。助けてくれてありがとう!