7

Fortran .dll に同一のソース ファイルを使用すると、Compaq Visual Fortran 6.6C または Intel Visual Fortran 12.1.3.300 (IA-32) でコンパイルできます。問題は、Intel バイナリでは実行が失敗することですが、Compaq では問題なく動作します。Windows 7 64 ビット システムで 32 ビットをコンパイルしています。.dll 呼び出しドライバーは、.dll で記述されていC#ます。

失敗メッセージは_chkstk()、内部サブルーチンが呼び出されたときの恐ろしい呼び出し (.dll エントリ ルーチンから呼び出された) から発生します。(だから答えてくださいchkstk()

問題の手順は次のように宣言されています(固定ファイル形式を許してください)

  SUBROUTINE SRF(den, crpm, icrpm, inose, qeff, rev,  
 &               qqmax, lvtyp1, lvtyp2, avespd, fridry, luin,  
 &               luout, lurtpo, ludiag, ndiag, n, nzdepth, 
 &               unit, unito, ier)

  INTEGER*4 lvtyp1, lvtyp2, luin, luout, lurtpo, ludiag, ndiag, n, 
 &          ncp, inose, icrpm, ier, nzdepth
  REAL*8    den, crpm, qeff, rev, qqmax, avespd, fridry           
  CHARACTER*2  unit, unito

そして次のように呼び出されます:

      CALL SRF(den, crpm(i), i, inose, qeff(i), rev(i),  
 &             qqmax(i), lvtyp1, lvtyp2, avespd, fridry, 
 &             luin, luout, lurtpo, ludiag, ndiag, n, nzdepth,  
 &             unit, unito, ier)

crpmqeffrevおよびを除いて同様の変数仕様を持つは、各呼び出しに要素qqmaxのみが使用される配列です。i-thSRF()

引数がサイズよりも大きい場合にスタックの問題が発生する可能性があることは理解しています8kbが、この場合7 x real(64) + 11 x int(32) + 2 x 2 x char(8) = 832 bits、渡された引数しかありません。

引数 (特に配列) をモジュールに移動するのに非常に苦労しましたが、同じエラーが発生し続けます

エラー.

Intel .dllからの分解は

インテル

Compaq .dllからの分解は、

コンパック

SOの原因やデバッグ方法について誰か提案できますか?

PS。予約済みのスタック スペースを数百に増やしましたがMb、問題は解決しません。逆アセンブラーで呼び出しをスキップしようとchkstk()しましたが、プログラムがクラッシュします。スタック チェックは、アドレスから始まり、ガード ページにアクセスしてクラッシュする場所まで0x354000反復されます。0x2D2000スタックのボトムアドレスは0x282000.

4

2 に答える 2

3

あなたは使者を撃っています。Compaqで生成されたコードは_chkstk()も呼び出しますが、違いはインライン化されていることです。一般的な最適化。2つのスニペットの主な違いは次のとおりです。

 mov eax, 0D3668h

vs

 sub esp, 233E4h

ここで使用されている値は、関数に必要なスタックスペースの量です。Intelコードには、0xd3668バイト=865869バイトが必要です。Compaqコードには0x233e4=144356が必要です。大きな違いがあります。どちらの場合も、それはかなり大量ですが、Intelのものが重要になりつつあり、プログラムには通常1メガバイトのスタックがあります。0.86メガバイトをゴブリングすると、非常に近くなり、いくつかの関数呼び出しがネストされ、このサイトの名前が表示されます。

あなたが知る必要があるのは、それがあなたのスニペットにないので私は助けることができません、それがインテルが生成した関数がそのローカル変数のために非常に多くのスペースを必要とする理由です。回避策は、フリーストアを使用して大きなアレイ用のスペースを見つけることです。または、リンカの/ STACKオプションを使用して、より多くのスタックスペースを要求します(オプション名を推測します)。

于 2012-06-09T18:32:23.773 に答える