逆アセンブリ分析を使用したLinux最小実行可能例
これは標準で指定されていない実装の詳細なので、コンパイラが特定の実装で何をしているかを見てみましょう。
この回答では、分析を行う特定の回答にリンクするか、ここに分析を直接提供し、すべての結果をここに要約します。
これらはすべてさまざまなUbuntu / GCCバージョンにあり、結果はバージョン間でかなり安定している可能性がありますが、バリエーションが見つかった場合は、より正確なバージョンを指定してみましょう。
関数内のローカル変数
それmain
か他の機能か:
void f(void) {
int my_local_var;
}
に示されているように、gdbで<valueoptimized out>はどういう意味ですか?
-O0
:スタック
-O3
:流出しない場合は登録し、それ以外の場合はスタックします
スタックが存在する理由の動機については、x86アセンブリのレジスターで使用されるプッシュ/ポップ命令の機能は何ですか?を参照してください。
グローバル変数とstatic
関数変数
/* BSS */
int my_global_implicit;
int my_global_implicit_explicit_0 = 0;
/* DATA */
int my_global_implicit_explicit_1 = 1;
void f(void) {
/* BSS */
static int my_static_local_var_implicit;
static int my_static_local_var_explicit_0 = 0;
/* DATA */
static int my_static_local_var_explicit_1 = 1;
}
- 初期化されている
0
か、初期化されていない場合(したがって暗黙的にに初期化されている場合0
):.bss
セクション、以下も参照してください:.bssセグメントが必要な理由
- それ以外の場合:
.data
セクション
char *
そして char c[]
に示されているように:CおよびC ++の静的変数はどこに格納されていますか?
void f(void) {
/* RODATA / TEXT */
char *a = "abc";
/* Stack. */
char b[] = "abc";
char c[] = {'a', 'b', 'c', '\0'};
}
TODO非常に大きな文字列リテラルもスタックに入れられますか?または.data
?それともコンパイルは失敗しますか?
関数の引数
void f(int i, int j);
関連する呼び出し規約を通過する必要があります。例:https : //en.wikipedia.org/wiki/X86_calling_conventions X86の場合はをます。これは、各変数の特定のレジスターまたはスタックの場所を指定します。
次に、「gdbでの<最適化された値>の意味」に示されているように?、-O0
しながら、スタックにすべてをslurps -O3
試行を極力レジスタを使用します。
ただし、関数がインライン化された場合は、通常のローカルと同様に扱われます。
const
あなたはそれをタイプキャストすることができるので、それは何の違いもないと信じています。
逆に、コンパイラーが一部のデータが書き込まれていないと判断できる場合、理論的には .rodata
はconstでなくます。
TODO分析。
ポインタ
これらは変数であり(数値であるアドレスを含みます)、残りすべてと同じです:-)
malloc
は関数なmalloc
ので、この質問はあまり意味がありませんmalloc
。
int *i = malloc(sizeof(int));
*i
はアドレスを含む変数なので、上記のケースに該当します。
mallocが内部でどのように機能するかについては、それを呼び出すと、Linuxカーネルが特定のアドレスを内部データ構造に書き込み可能としてマークし、プログラムが最初にそれらに触れたときに障害が発生し、カーネルがページテーブルを有効にして、アクセスを許可しますsegfaulなしで発生:x86ページングはどのように機能しますか?
注ただし、これはまさに、基本的であることをexec
あなたが実行可能ファイルを実行しようとすると、システムコールは、ボンネットの下に行われます。それがロードしたいことマークページ、およびそこにプログラムを書き込み、また、以下を参照してください下を実行しているどのようにカーネルのget実行可能なバイナリファイルをLinux?ただし、exec
ロード先に追加の制限がある(ただし、コードが再配置可能ではないなど)。
使用される正確なsyscall malloc
はmmap
、現代の2020実装であり、過去brk
に使用されていました。malloc()はbrk()またはmmap()を使用しますか?
動的ライブラリ
基本的mmap
にメモリを確保する:https : //unix.stackexchange.com/questions/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710
envinroment変数やmain
さんargv
初期スタックの上:https : //unix.stackexchange.com/questions/75939/where-is-the-environment-string-actual-stored TODOなぜ.dataにないのですか?