Dalam dunia pemrograman tingkat rendah (low-level programming), ada satu konsep yang jika tidak dipahami, akan membuat seluruh sistem kita runtuh: Stack.
Jika Anda sedang belajar membangun sistem operasi atau menulis bahasa Assembly, Stack bukan sekadar “pilihan”, melainkan infrastruktur wajib. Artikel ini akan membedah Stack mulai dari anatomi hingga implementasi kodenya.
1. Apa Itu Stack? (Filosofi LIFO)
Secara struktur data, Stack adalah area memori yang bekerja dengan prinsip LIFO (Last-In, First-Out). Artinya, data yang terakhir masuk adalah data yang pertama kali akan dikeluarkan.
Bayangkan sebuah tabung kepingan koin. Anda memasukkan koin satu per satu dari atas. Untuk mengambil koin yang paling bawah, Anda dipaksa mengeluarkan semua koin yang ada di atasnya terlebih dahulu. Dalam komputer, “koin” ini adalah data atau alamat memori.
2. Kenapa Stack Tumbuh ke Bawah?
Ini adalah bagian yang sering membingungkan pemula. Di arsitektur komputer x86, Stack secara fisik tumbuh dari alamat memori tinggi ke alamat memori rendah.
- Top of Stack: Alamat memori paling rendah (berisi data terbaru).
- Bottom of Stack: Alamat memori paling tinggi (tempat data pertama kali diletakkan).
Kenapa desainnya begini?
Secara tradisional, memori dibagi menjadi dua kutub. Data biasa (disebut Heap) tumbuh ke atas, sedangkan Stack tumbuh ke bawah. Mereka saling mendekat di tengah-tengah ruang kosong RAM. Tujuannya agar penggunaan ruang RAM menjadi maksimal dan tidak ada ruang yang terbuang percuma.
3. Mengenal Sang Penjaga: Register SS dan SP
Untuk mengelola tumpukan ini, CPU menyediakan dua “asisten” khusus yang disebut Register:
- SS (Stack Segment): Menentukan di blok memori mana tumpukan kita berada.
- SP (Stack Pointer): Ini adalah penunjuk yang sangat sibuk. Ia selalu menunjuk tepat ke data yang berada di paling atas tumpukan saat ini.
Setiap kali kita melakukan PUSH (memasukkan data), nilai SP akan berkurang. Sebaliknya, saat POP (mengambil data), nilai SP akan bertambah.
Logika dasarnya:
- PUSH: SP = SP – 2 (Mengurangi alamat untuk memberi ruang data baru).
- POP: SP = SP + 2 (Menambah alamat karena data sudah diambil).
4. Demonstrasi Kode: Membalikkan Urutan
Mari kita lihat kekuatan Stack dalam kode Assembly. Kita akan memasukkan huruf ‘A’, ‘B’, dan ‘C’ ke dalam Stack, lalu mengambilnya kembali. Karena sifat LIFO, urutan yang muncul di layar secara ajaib akan terbalik menjadi ‘C’, ‘B’, ‘A’.
[bits 16]
[org 0x7c00]
; --- 1. Persiapan Stack ---
mov ax, 0x0000
mov ss, ax ; Mengatur segmen stack ke 0x0000
mov sp, 0x9000 ; Memulai pointer stack di alamat 0x9000 (area aman)
; --- 2. Menyimpan Data (PUSH) ---
mov ax, 'A'
push ax ; SP sekarang di 0x8FFE
mov ax, 'B'
push ax ; SP sekarang di 0x8FFC
mov ax, 'C'
push ax ; SP sekarang di 0x8FFA
; --- 3. Mengambil Data (POP) ---
; Karena LIFO, data 'C' akan keluar pertama kali.
pop ax ; AX sekarang berisi 'C'
mov ah, 0x0e
int 0x10 ; Layar mencetak 'C'
pop ax ; AX sekarang berisi 'B'
int 0x10 ; Layar mencetak 'B'
pop ax ; AX sekarang berisi 'A'
int 0x10 ; Layar mencetak 'A'
jmp $ ; Selesai, kunci CPU
times 510-($-$$) db 0
dw 0xaa55
5. Mengapa Kernel Sangat Butuh Stack?
Tanpa Stack, kita tidak akan pernah bisa membuat sistem operasi yang stabil. Berikut adalah tiga fungsi vitalnya:
- Panggilan Fungsi (Subroutine): Saat program memanggil fungsi, CPU menyimpan “alamat pulang” di Stack. Tanpa ini, CPU akan tersesat dan tidak tahu harus kembali ke baris mana setelah fungsi selesai.
- Penyimpanan Register: CPU hanya punya sedikit tempat penyimpanan (register). Jika kita butuh register tersebut untuk tugas lain, kita “titipkan” nilai lamanya di Stack, lalu kita ambil lagi nanti.
- Variabel Lokal: Semua variabel yang Anda buat di dalam fungsi (pada bahasa C atau Java) sebenarnya hidup di dalam Stack dan akan mati (dihapus) secara otomatis saat fungsi selesai.
Kesimpulan
Stack bukan sekadar tumpukan data biasa. Ia adalah mekanisme navigasi utama CPU. Memahami Stack adalah langkah pertama bagi siapa pun yang ingin menjadi pengembang sistem operasi atau programmer tingkat rendah yang andal.
