0

次のコードがあると想像してください

void A(){
// blah blah blah
}
void B(){
// blah blah blah
}
void C(){
// blah blah blah
}

コードを (Visual Studio を使用して) コンパイルし、メモリにロードして実行すると、A()、B()、C() のアドレスが順番どおりにならない場合があります。どうすれば注文できますか?この状況で役立つディレクティブはありますか?

4

2 に答える 2

3

プログラムが単一の翻訳単位 (ソース ファイル) で構成されている場合、結果のバイナリには通常、翻訳単位で定義されている順序で関数が含まれている必要があります。たとえば、次のプログラムを考えてみましょう。

int A() { return  0; }
int B() { return  1; }
int C() { return -1; }

int main() { return A() + B() + C(); }

このプログラムを最小サイズ (/O1) に最適化し、インライン関数展開を無効にして (/Ob0) コンパイルすると、次のマシン コードが生成されます。

int A() { return  0; }
00F71000 33 C0                xor         eax,eax  
00F71002 C3                   ret  
int B() { return  1; }
00F71003 33 C0                xor         eax,eax  
00F71005 40                   inc         eax  
00F71006 C3                   ret  
int C() { return -1; }
00F71007 83 C8 FF             or          eax,0FFFFFFFFh  
00F7100A C3                   ret  

int main() { return A() + B() + C(); }
00F7100B E8 F0 FF FF FF       call        A (0F71000h)  
00F71010 8B C8                mov         ecx,eax  
00F71012 E8 EC FF FF FF       call        B (0F71003h)  
00F71017 03 C8                add         ecx,eax  
00F71019 E8 E9 FF FF FF       call        C (0F71007h)  
00F7101E 03 C1                add         eax,ecx  
00F71020 C3                   ret  

ソース注釈は、デバッガーによって提供されます。最小サイズの最適化はint 3、他の最適化設定が使用されている場合に関数間に配置されるパディングをなくすために必要です。結果のバイナリに関数が実際に存在することを確認するには、インライン関数展開を無効にする必要があります。

これは、私の知る限り、実装の詳細であるため、製品コードに依存するべきではありません。

于 2012-10-20T05:15:02.720 に答える
0

読みやすくするためにそれらを個別の関数に分割し、プログラム全体で一度だけ呼び出す場合は、これらの関数をインラインで宣言すると、コンパイラは呼び出し命令なしでそれらを単一のコードに結合します。

それ以外の場合、呼び出し命令は CPU のパイプラインをフラッシュするため、それらをメモリに順番に配置する理由はありません。

于 2012-10-20T04:25:59.430 に答える