静的変数は、最初の世界的なバーということで、グローバル静的変数、静的ローカル変数に分けることができます。グローバルな静的変数とグローバル変数間の差は大きくありませんが、グローバル静的変数は、現在のファイルで使用することができ、そしてそこに、あなただけの現在のファイルで使用することができます解体中2の間に違いはありませんが、コンパイラによって作られます制限。ローカル静的変数は、いくつかの特別になり、それは、スコープの終わりに消える前に存在していないに施行されたことはありません。ローカル静的変数とグローバル変数は、バイナリファイルのデータ領域に格納され、コードの制約が、コンパイラはそれを制限しています。
コードを見てください:
ボイド ShowStatic(INT NNUM) { 静的 INT gnNumber = NNUM。 printf(" %dの\ n " 、gnNumber)。 } ボイドメイン() { ShowStatic(99 )。 }
アセンブリコード:
00E51738 MOV EAX、DWORD PTR DS:[00E5A148h] 00E5173D 及び EAX、1 00E51740 JNE ShowStatic + 47H(0E51757h) 00E51742 MOV EAX、DWORD PTR DS:[00E5A148h] 00E51747 又は EAX、1 00E5174A MOV DWORD PTR DS:[00E5A148h] EAX 00E5174F MOV EAX、DWORD PTR [NNUM] 00E51752 MOV DWORD PTR [gnNumber(0E5A144h)]、EAX
図から分かるように、多くの静的変数の割り当ての割り当ては、平均的な変数よりも、私たちは分析しなければならない手順。
まず、アドレス00E5A148hでマークローカル静的変数の保存、このフラグは1バイトです。ビット操作により、データセット内のフラグは、ローカル静的変数が初期化されたか否かを判定する。そして、この記号は、同時に8つのローカル静的変数の初期状態を保存することができます。
このフラグは、一般的に、本実施形態の第1の実施例で定義された変数はローカル変数または00E5A144hで00E5A14Chに表示されるべきローカル静的近くで生じます。今ことを除いて8静的ローカル変数と同じスコープは、次の近くの最初の9つのマーカーで定義されたローカル静的変数に取り組むとき。今、上記のアセンブリコードを見ては非常に明確です:
00E51738 MOV EAX、DWORD PTR DS:[00E5A148h] 00E5173D 及び EAX、1 00E51740 JNE ShowStatic + 47H(0E51757h)
オフが初期化されているかどうか、それはprintfの出力内容にジャンプを初期化されている、または継続してジャンプしない場合。
00E51742 MOV EAX、DWORD PTR DS:[00E5A148h] 00E51747 又は EAX、1 00E5174A MOV DWORD PTR DS:[00E5A148h]、EAX 00E5174F MOV EAX、DWORD PTR [NNUM] 00E51752 MOV DWORD PTR [gnNumber(0E5A144h)]、EAX
初期化せずに、フラグが1に設定され、gnNumber初期化されます。
このような問題は、コンパイラのローカル静的変数の他のスコープが表示されていないので、これが行う方法ではありますか?コンパイル中に、コンパイラは、変数、関数など粉砕した名前であることを、静的変数の名前が変更されます。
下に示すように、我々は、検索結果、ファイル名(この記事はオープンOBJファイルHXDソフトウェア)で静的変数を検索し、次のコンパイルOBJファイルの終了後に生成された観察しました:
名前を破砕した後、元の名前に加えていくつかの余分な情報、範囲、種類などを追加しました。C ++のオーバーロードのようにも原理を破砕の名前です。
静的int型 gnNumber = NNUM 。 00C11818 MOV EAX、DWORD PTR [_tls_index(0C1B190h)] 00C1181D MOV ECX、DWORD PTR FS:[2歴] 00C11824 MOV EDX、DWORD PTR [ECX + EAX * 4 ] 00C11827 MOV EAX、DWORD PTR DS:[00C1B150h] 00C1182C CMP EAX 、DWORD PTR [EDX + 104H] 00C11832 JLE ShowStatic + 6FH(0C1185Fh) 00C11834 プッシュ 0C1B150h 00C11839 コール __Init_thread_header(0C110DCh) 00C1183Eが 追加 ESP、4 00C11841 CMP DWORD PTR DS:[0C1B150h]、0FFFFFFFFH 00C11848 JNE ShowStatic + 6FH(0C1185Fh) 00C1184A MOV EAX、DWORD PTR [NNUM] 00C1184D MOV DWORD PTR [gnNumber(0C1B14Ch)]、EAX 00C11852 プッシュ 0C1B150h 00C11857 コールを __Init_thread_footer(0C11177h) 00C1185C 追加 ESP、4
コードの最初の3行:
00C11818 MOV EAX、DWORD PTR [_tls_index(0C1B190h)] 00C1181D MOV ECX、DWORD PTR FS:[2歴] 00C11824 MOV EDX、DWORD PTR [ECX + EAX * 4 ]
TLS?どのように二つ以上の機能?__Init_thread_header
そして、_Init_thread_footer。
これら二つの機能は、ローカル静的オブジェクトの安全性を確保するためにスレッドを初期化するために使用されています。しかし、まだ同じミューテックスローカル変数が、前述の二つの機能にカプセル化されます。