Tumpukan panggilan dimulai dari bawah atau atas?

10

Tumpukan adalah sesuatu yang menumpuk dari bawah ke atas.

Oleh karena itu tumpukan panggilan menambahkan item baru di tumpukan ketika fungsi dipanggil dengan item yang dihapus dari tumpukan karena setiap fungsi berakhir sampai tumpukan kosong dan kemudian program berakhir.

Jika hal di atas benar, mengapa orang-orang merujuk kontrol naik "naik" panggilan stack? Tentunya kontrol bergerak ke bawah tumpukan panggilan hingga mencapai bagian bawah.

CJ7
sumber
Ketika fungsi dipanggil, item ditambahkan ke bagian atas tumpukan, dan kontrol dilewatkan ke fungsi itu. Oleh karena itu kontrol bergerak dari item yang mendasarinya di tumpukan ke item teratas - ke atas.
treecoder
1
@greengit: ungkapan "naikkan tumpukan panggilan" digunakan dengan pengecualian, di mana kontrol benar-benar bergerak dengan cara yang berlawanan.
Michael Borgwardt
@MichaelBorgwardt: Anda benar.
treecoder
1
@MichaelBorgwardt: Saya telah melihat ungkapan "kesalahan naik ke tumpukan panggilan". Tentunya itu tidak benar.
CJ7

Jawaban:

8

Ada dua kemungkinan alasan untuk penggunaan ini:

  • Dalam konteks pengecualian, kontrol berpindah ke fungsi / metode pemanggilan, dan hierarki panggilan ini biasanya divisualisasikan dengan metode utama di atas dan pemanggilan metode yang membentuk hierarki ke bawah, dengan tingkat abstraksi yang menurun. Dalam hierarki ini, pengecualian bergerak ke atas.

  • Tumpukan program aktual dalam aplikasi x86 normal dibalik, yaitu tumbuh ke bawah. Instruksi kode mesin PUSH / PUSHW / PUSHD mengurangi penunjuk tumpukan. Arsitektur lain mungkin berbagi model ini.

Michael Borgwardt
sumber
Bukankah ide top-down bertentangan dengan konsep sehari-hari "tumpukan" menjadi tumpukan item mulai dari bawah?
CJ7
@CraigJ: jadi adalah kenyataan bahwa bit setiap byte dari isi stack akan secara fisik disimpan dalam chip yang terpisah. Siapa peduli?
Michael Borgwardt
1

Itu semua tergantung pada definisi kata; apa sebenarnya yang Anda maksud dengan kata-kata "atas" dan "bawah" dalam konteks ini, dan juga pada implementasi sistem operasi atau arsitektur komputer.

Saya ingat yang berikut dari dulu, ketika saya pemrograman di Commodore 64. Memori antara alamat $ 0800 (2048) dan $ 9FFF (40959) dicadangkan untuk program BASIC. Kode program BASIC Anda disimpan mulai dari alamat yang lebih rendah ($ 0800, tumbuh ke atas dari sana). Tumpukan, untuk menyimpan variabel dan mengembalikan alamat subrutin, mulai di bagian atas ($ 9FFF) dari rentang itu dan tumbuh menuju alamat yang lebih rendah. Jadi dalam konteks ini adalah logis untuk melihat tumpukan tumbuh ke bawah, dan ketika Anda kembali dari subrutin bingkai tumpukan subrutin dibuang dengan menambah penunjuk tumpukan, sehingga Anda bisa mengatakan Anda "bergerak naik tumpukan" ketika kembali dari subrutin.

Saya tidak tahu cara kerjanya pada versi modern, misalnya untuk prosesor Windows atau Intel x86. Mungkin tumpukan bekerja sebaliknya, yaitu tumbuh dari alamat yang lebih rendah ke yang lebih tinggi. Jika itu yang terjadi maka Anda mungkin akan menggunakan kata "atas", "bawah" dan "atas", "turun" persis sebaliknya.

Jesper
sumber
0

Untuk memanggil fungsi seperti foo (6, x + 1) ...

  1. Mengevaluasi ekspresi parameter aktual, seperti x + 1, dalam konteks pemanggil.
  2. Alokasikan memori untuk penduduk setempat foo () dengan mendorong "blok lokal" memori yang sesuai ke "tumpukan panggilan" runtime yang didedikasikan untuk tujuan ini. Untuk parameter tetapi bukan variabel lokal, simpan nilai dari langkah (1) ke dalam slot yang sesuai di blok lokal foo ().
  3. Simpan alamat eksekusi pemanggil saat ini ("alamat pengirim") dan alihkan eksekusi ke foo ().
  4. foo () dijalankan dengan blok lokalnya tersedia di akhir tumpukan panggilan.
  5. Ketika foo () selesai, ia keluar dengan mengeluarkan penduduk setempat dari tumpukan dan "kembali" ke pemanggil menggunakan alamat pengembalian yang disimpan sebelumnya. Sekarang penduduk lokal penelepon berada di ujung tumpukan dan dapat melanjutkan eksekusi.

Referensi:

http://cslibrary.stanford.edu/102/PointersAndMemory.pdf (p15)

CodeART
sumber
Perhatikan bahwa ini sangat spesifik untuk konvensi pemanggilan. Ada konvensi panggilan yang memungkinkan penelepon membersihkan, sebagian besar menggunakan setidaknya beberapa register, dll.
0

Jika Anda mengonseptualisasikan tumpukan sebagai hal dari bawah ke atas, seperti sebuah silinder dengan bola tenis di dalamnya di bawah realitas gravitasi normal, maka kendali akan bergerak ke atas tumpukan itu sebagaimana fungsinya disebut. Saat fungsi selesai, kontrol bergerak ke bawah tumpukan.

Jika Anda mengonseptualisasikan tumpukan sebagai hal dari atas ke bawah, seperti silinder bola tenis yang sama tetapi dengan gravitasi terbalik, maka kontrol bergerak turun ke atas tumpukan saat fungsi dipanggil dan naik ke tumpukan sebagai fungsi selesai.

Keduanya adalah model di kepala Anda dan pada dasarnya sepenuhnya arbitrer. Anda dapat mengonseptualisasikannya sebagai hal dari sisi ke sisi jika Anda mau, tetapi mungkin mengalami kesulitan berkomunikasi dengan orang-orang. Saya pribadi berpikir bahwa jika A memanggil B dan B memanggil C bahwa C adalah bagian bawah tumpukan (realitas gravitasi terbalik) dan jika pengecualian terjadi dalam C Anda ingin menggembungkan pengecualian "hingga" ke A. Saya pikir ini mungkin penggunaan bahasa yang lebih umum karena perasaannya adalah bahwa C jauh di dalam dan A adalah yang teratas. Fungsi pertama lebih intuitif bagi saya dan fungsi semakin dalam pada setiap panggilan.

Ken Falk
sumber