Di mana itu didorong?
esp - 4
. Lebih tepatnya:
esp
akan dikurangi 4
- nilai didorong ke
esp
pop
membalikkan ini.
System V ABI memberi tahu Linux untuk rsp
menunjukkan lokasi stack yang masuk akal ketika program mulai berjalan: Apa status register default ketika program diluncurkan (asm, linux)? yang biasanya Anda gunakan.
Bagaimana Anda bisa mendaftar?
Contoh GNU GAS Minimal:
.data
/* .long takes 4 bytes each. */
val1:
/* Store bytes 0x 01 00 00 00 here. */
.long 1
val2:
/* 0x 02 00 00 00 */
.long 2
.text
/* Make esp point to the address of val2.
* Unusual, but totally possible. */
mov $val2, %esp
/* eax = 3 */
mov $3, %ea
push %eax
/*
Outcome:
- esp == val1
- val1 == 3
esp was changed to point to val1,
and then val1 was modified.
*/
pop %ebx
/*
Outcome:
- esp == &val2
- ebx == 3
Inverses push: ebx gets the value of val1 (first)
and then esp is increased back to point to val2.
*/
Di atas di GitHub dengan pernyataan yang dapat dijalankan .
Mengapa ini dibutuhkan?
Memang benar bahwa instruksi tersebut dapat dengan mudah diimplementasikan melalui mov
, add
dan sub
.
Alasan mereka ada, adalah karena kombinasi instruksi tersebut sangat sering, sehingga Intel memutuskan untuk menyediakannya untuk kami.
Alasan mengapa kombinasi tersebut sangat sering, adalah karena kombinasi tersebut memudahkan untuk menyimpan dan memulihkan nilai register ke memori sementara sehingga tidak ditimpa.
Untuk memahami masalahnya, coba kompilasi beberapa kode C secara manual.
Kesulitan utama, adalah memutuskan di mana setiap variabel akan disimpan.
Idealnya, semua variabel akan masuk ke dalam register, yang merupakan memori tercepat untuk diakses (saat ini sekitar 100x lebih cepat dari RAM).
Tetapi tentu saja, kita dapat dengan mudah memiliki lebih banyak variabel daripada register, khususnya untuk argumen fungsi bersarang, jadi satu-satunya solusi adalah menulis ke memori.
Kita bisa menulis ke alamat memori apa pun, tetapi karena variabel lokal dan argumen pemanggilan dan pengembalian fungsi cocok dengan pola tumpukan yang bagus, yang mencegah fragmentasi memori , itulah cara terbaik untuk mengatasinya. Bandingkan dengan kegilaan menulis pengalokasi heap.
Kemudian kita biarkan kompiler mengoptimalkan alokasi register untuk kita, karena itu adalah NP lengkap, dan salah satu bagian tersulit dalam menulis kompilator. Masalah ini disebut alokasi register , dan itu isomorfik untuk pewarnaan graf .
Ketika pengalokasi kompiler dipaksa untuk menyimpan sesuatu dalam memori dan bukan hanya register, itu dikenal sebagai spill .
Apakah ini bermuara pada instruksi prosesor tunggal atau lebih kompleks?
Yang kita tahu pasti adalah bahwa Intel mendokumentasikan a push
dan pop
instruksi, jadi mereka adalah satu instruksi dalam pengertian itu.
Secara internal, ini dapat diperluas ke beberapa mikrokode, satu untuk memodifikasi esp
dan satu untuk melakukan IO memori, dan mengambil banyak siklus.
Tapi mungkin juga itu single push
lebih cepat daripada kombinasi setara dari instruksi lain, karena lebih spesifik.
Ini sebagian besar tidak (der) didokumentasikan:
b
,w
,l
, atauq
untuk menunjukkan ukuran memori dimanipulasi. Contoh:pushl %eax
danpopl %eax