Sökme analizine sahip Linux ile minimum çalıştırılabilir örnekler
Bu, standartlar tarafından belirtilmeyen bir uygulama ayrıntısı olduğundan, derleyicinin belirli bir uygulamada ne yaptığını inceleyelim.
Bu cevapta, analizi yapan spesifik cevaplarla bağlantı kuracağım veya doğrudan burada analiz sağlayacağım ve tüm sonuçları burada özetleyeceğim.
Bunların hepsi çeşitli Ubuntu / GCC sürümlerinde ve sonuçlar sürümler arasında oldukça kararlı, ancak herhangi bir varyasyon bulursak daha kesin sürümler belirleyelim.
Bir fonksiyon içindeki yerel değişken
İster main
başka bir fonksiyon olsun:
void f(void) {
int my_local_var;
}
Gösterildiği gibi: gdb'de <optimize edilmiş değer> ne anlama geliyor?
-O0
: yığın
-O3
: dökülmezlerse kaydolur, aksi halde istifler
Yığının neden var olduğuna dair motivasyon için bkz: x86 derlemesindeki kayıtlarda kullanılan push / pop talimatlarının işlevi nedir?
Global değişkenler ve static
fonksiyon değişkenleri
/* 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;
}
- başlatıldı eğer
0
ya da değil başlatıldı (ve bu nedenle dolaylı olarak başlatıldı 0
): .bss
bölüm, ayrıca bkz: Neden .bss segmenti gereklidir?
- aksi takdirde:
.data
bölüm
char *
ve char c[]
Gösterildiği gibi: Statik değişkenler C ve C ++ 'da nerede saklanır?
void f(void) {
/* RODATA / TEXT */
char *a = "abc";
/* Stack. */
char b[] = "abc";
char c[] = {'a', 'b', 'c', '\0'};
}
YAPILACAKLAR Çok büyük dize değişmezleri de yığına konacak mı? Yoksa .data
? Yoksa derleme başarısız mı?
İşlev bağımsız değişkenleri
void f(int i, int j);
İlgili çağrı kuralından geçmelidir, örneğin: her değişken için belirli kayıtları veya yığın konumlarını belirten X86 için https://en.wikipedia.org/wiki/X86_calling_conventions .
Daha sonra gösterildiği gibi <optimize edilmiş değer> gdb'de ne anlama geliyor? , -O0
daha sonra kayıtları -O3
mümkün olduğunca kullanmaya çalışırken , her şeyi yığına kaydırır .
Ancak işlev satır içine girerse, normal yerliler gibi davranılır.
const
Fark etmediğine inanıyorum çünkü tahmin edebiliyorsunuz.
Tersine, eğer derleyici bazı verinin asla yazılmadığını belirleyebiliyorsa, teorik olarak veri .rodata
olmasa bile veriyi yerleştirebilir .
YAPILACAKLAR analizi.
İşaretçiler
Değişkenlerdir (sayı içeren adresler içerir), diğerleriyle aynı :-)
malloc
Sorusu için çok mantıklı değil malloc
, çünkü malloc
bir fonksiyondur ve içinde:
int *i = malloc(sizeof(int));
*i
adres içeren bir değişkendir, bu nedenle yukarıdaki duruma düşer.
Malloc'un dahili olarak nasıl çalıştığına gelince, Linux çekirdeği olarak adlandırdığınızda, Linux çekirdeği belirli adresleri dahili veri yapılarında yazılabilir olarak işaretler ve başlangıçta program tarafından dokunulduğunda, bir hata olur ve çekirdek, erişime izin veren sayfa tablolarını etkinleştirir. segfaul olmadan olur: x86 sayfalama nasıl çalışır?
Bununla birlikte, temelde exec
bir çalıştırılabilir dosyayı çalıştırmaya çalıştığınızda syscall'ın tam olarak kaputun altında yaptığı şey olduğunu unutmayın : yüklemek istediği sayfaları işaretler ve programı oraya yazar, ayrıca bkz: Çekirdek altında çalışan bir yürütülebilir ikili dosyayı nasıl alır? linux? Bunun exec
nereye yükleneceği konusunda bazı ekstra sınırlamaları dışında (örneğin, kodun yeri değiştirilemez ).
İçin kullanılan tam syscall malloc
olan mmap
Modern 2020 uygulamalarda ve geçmişte brk
kullanılmıştır: mu malloc () kullanımı brk () veya mmap ()?
Dinamik kütüphaneler
Temelde mmap
hafızaya alın: /unix/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710
envinroment değişkenler ve main
sitesindekiargv
İlk yığının üstünde: /unix/75939/where-is-the-environment-string-actual-stored TODO neden .data'da olmasın?