Saya mencoba memahami bagaimana susunan bingkai dibangun dan variabel (params) mana yang didorong untuk ditumpuk dalam urutan apa? Beberapa hasil pencarian menunjukkan bahwa kompiler C / C ++ memutuskan berdasarkan operasi yang dilakukan dalam suatu fungsi. Misalnya, jika fungsi seharusnya hanya menambah nilai int pass-in oleh 1 (mirip dengan operator ++) dan mengembalikannya, itu akan menempatkan semua parameter fungsi dan variabel lokal ke dalam register.
Saya ingin tahu register mana yang digunakan untuk mengembalikan atau melewati parameter nilai. Bagaimana referensi dikembalikan? Bagaimana kompiler memilih antara eax, ebx, ecx dan edx?
Apa yang perlu saya ketahui untuk memahami bagaimana register, tumpukan dan tumpukan referensi digunakan, dibangun dan dihancurkan selama pemanggilan fungsi?
Jawaban:
Selain apa yang Dirk katakan, penggunaan penting dari frame tumpukan adalah untuk menyimpan nilai register sebelumnya sehingga mereka dapat dikembalikan setelah panggilan fungsi. Jadi, bahkan pada prosesor di mana register digunakan untuk melewati parameter, mengembalikan nilai, dan menyimpan alamat kembali, nilai register tersebut disimpan di stack sebelum panggilan fungsi sehingga mereka dapat dikembalikan setelah panggilan. Ini memungkinkan satu fungsi untuk memanggil yang lain tanpa menimpa parameternya sendiri atau lupa alamat pengirimnya sendiri.
Jadi, memanggil fungsi B dari fungsi A pada sistem "generik" yang khas mungkin melibatkan langkah-langkah berikut:
Ini sama sekali bukan satu-satunya cara pemanggilan fungsi dapat bekerja (dan saya mungkin memiliki satu atau dua langkah keluar dari urutan), tetapi seharusnya memberi Anda gambaran tentang bagaimana stack digunakan untuk membiarkan prosesor menangani panggilan fungsi yang disarangkan.
sumber
push
danpop
merupakan dua operasi mendasar pada stack. Tumpukan adalah struktur masuk terakhir keluar pertama, seperti tumpukan buku. Saat Andapush
, Anda meletakkan objek baru di atas tumpukan; saat Andapop
mengambil objek dari atas tumpukan. Anda tidak diizinkan untuk menyisipkan atau menghapus objek di tengah, Anda hanya dapat beroperasi di atas tumpukan. Anda mungkin membaca lebih lanjut tentang tumpukan secara umum dan tumpukan program khususnya di Wikipedia.Ini tergantung pada konvensi panggilan yang digunakan. Siapa pun yang mendefinisikan konvensi pemanggilan dapat membuat keputusan ini bagaimanapun yang mereka inginkan.
Dalam konvensi panggilan paling umum pada x86, register tidak digunakan untuk melewatkan parameter; parameter didorong ke tumpukan dimulai dengan parameter paling kanan. Nilai kembali ditempatkan di eax dan dapat menggunakan edx jika membutuhkan ruang ekstra. Referensi dan pointer keduanya dikembalikan dalam bentuk alamat di eax.
sumber
Jika Anda memahami tumpukan dengan sangat baik maka Anda akan memahami bagaimana memori bekerja dalam program dan jika Anda memahami bagaimana memori bekerja dalam program, Anda akan memahami bagaimana fungsi menyimpan dalam program dan jika Anda memahami bagaimana fungsi menyimpan dalam program Anda akan memahami bagaimana fungsi rekursif bekerja dan jika Anda memahami bagaimana fungsi rekursif bekerja, Anda akan memahami cara kerja kompiler dan jika Anda memahami cara kerja kompiler, pikiran Anda akan berfungsi sebagai kompiler dan Anda akan men-debug program apa pun dengan sangat mudah
Biarkan saya menjelaskan cara kerja tumpukan:
Pertama, Anda harus tahu bagaimana fungsi menyimpan di stack:
Heap menyimpan nilai alokasi memori dinamis. Nilai alokasi dan penghapusan otomatis tumpukan disimpan.
Mari kita pahami dengan contoh:
Sekarang pahami bagian dari program ini:
Sekarang mari kita lihat apa itu stack dan apa itu stack parts:
Ingat satu hal jika ada fungsi mendapatkan "kembali" tidak peduli itu telah memuat semua variabel lokalnya atau apa pun itu akan segera kembali dari tumpukan akan bingkai tumpukannya. Ini berarti ketika setiap fungsi rekursif mendapatkan kondisi basis dan kami mengembalikannya setelah kondisi dasar sehingga kondisi basis tidak akan menunggu untuk memuat variabel lokal yang terletak di bagian "lain" dari program, ia akan segera mengembalikan frame saat ini dari stack dan sekarang jika satu frame kembali frame berikutnya dalam catatan aktivasi. Lihat ini secara praktis:
Jadi sekarang setiap kali fungsi ditemukan pernyataan kembali itu menghapus bingkai saat ini dari tumpukan.
saat kembali dari nilai tumpukan akan kembali dalam urutan terbalik di mana mereka dialokasikan dalam tumpukan.
Ini adalah deskripsi yang sangat singkat dan jika Anda ingin tahu lebih dalam tentang stack dan double recursion baca dua posting blog ini:
Lebih lanjut tentang tumpukan langkah demi langkah
Lebih lanjut tentang rekursi ganda langkah demi langkah dengan tumpukan
sumber
Apa yang Anda cari disebut Application Binary Interface - ABI.
Ada spesifikasi untuk setiap kompiler yang merinci ABI.
Setiap platform biasanya akan menentukan dan ABI untuk mendukung interoperabilitas antar kompiler. Sebagai contoh, Konvensi Memanggil x86 merinci konvensi pemanggilan khas untuk x86 dan x86-64. Saya mengharapkan dokumen yang lebih resmi daripada wikipedia.
sumber