アセンブリに関するこのチュートリアルに従っています。
チュートリアル (私もローカルで試したところ、同様の結果が得られました) によると、次のソース コード:
int natural_generator() { int a = 1; static int b = -1; b += 1; /* (1, 2) */ return a + b; }
次のアセンブリ命令にコンパイルします。
$ gdb static (gdb) break natural_generator (gdb) run (gdb) disassemble Dump of assembler code for function natural_generator: push %rbp mov %rsp,%rbp movl $0x1,-0x4(%rbp) mov 0x177(%rip),%eax # (1) add $0x1,%eax mov %eax,0x16c(%rip) # (2) mov -0x4(%rbp),%eax add 0x163(%rip),%eax # 0x100001018 <natural_generator.b> pop %rbp retq End of assembler dump.
(行番号のコメント(1)
、(2)
および(1, 2)
私が追加しました。)
質問:コンパイルされたコードでは、静的変数のアドレスが命令ポインター (RIP) に相対的であり、特定のセクションに相対的ではなく、常に変化し (行と行を参照)、より複雑なアセンブリ コードを生成するのはなぜですか?そのような変数はどこに保存されますか?b
(1)
(2)
前述のチュートリアルによると、次のようなセクションがあります。
これは、 の値がサンプル実行可能ファイルの別のセクション
b
にハードコードされており、プロセスの起動時にオペレーティング システムのローダーによってすべてのマシン コードと共にメモリに読み込まれるためです。
(私のものを強調してください。)