Nereye itiliyor?
esp - 4
. Daha kesin:
esp
4 çıkarılır
- değer itilir
esp
pop
bunu tersine çeviriyor.
System V ABI, Linux'a rsp
, program çalışmaya başladığında makul bir yığın konumuna işaret etmesini söyler : Program başladığında (asm, linux) varsayılan kayıt durumu nedir? bu genellikle kullanmanız gereken şeydir.
Bir kaydı nasıl itebilirsiniz?
Minimal GNU GAS örneği:
.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.
*/
Yukarıdaki çalıştırılabilir iddialarla GitHub'da .
Bu neden gerekli?
Bu talimatların mov
, add
ve aracılığıyla kolayca uygulanabileceği doğrudur sub
.
Var olmalarının nedeni, bu talimat kombinasyonlarının o kadar sık olması ki Intel bunları bizim için sağlamaya karar verdi.
Bu kombinasyonların bu kadar sık olmasının nedeni, yazmaçların değerlerini geçici olarak belleğe kaydetmeyi ve geri yüklemeyi kolaylaştırmaları ve böylece üzerine yazılmamalarıdır.
Sorunu anlamak için, bazı C kodunu elle derlemeyi deneyin.
En büyük zorluk, her değişkenin nerede saklanacağına karar vermektir.
İdeal olarak, tüm değişkenler, erişilmesi en hızlı bellek olan (şu anda RAM'den yaklaşık 100 kat daha hızlı ) yazmaçlara sığacaktır .
Ama elbette, özellikle iç içe geçmiş fonksiyonların argümanları için yazmaçlardan daha fazla değişkene sahip olabiliriz, bu yüzden tek çözüm belleğe yazmaktır.
Herhangi bir bellek adresine yazabiliriz, ancak işlev çağrılarının ve geri dönüşlerinin yerel değişkenleri ve argümanları, bellek parçalanmasını önleyen güzel bir yığın modeline uyduğundan , bununla başa çıkmanın en iyi yolu budur. Bunu bir yığın ayırıcı yazmanın çılgınlığıyla karşılaştırın.
Ardından, derleyicilerin bizim için yazmaç tahsisini optimize etmelerine izin veriyoruz, çünkü bu NP tamamlandı ve bir derleyici yazmanın en zor kısımlarından biri. Bu soruna kayıt ayırma denir ve grafik renklendirmesi izomorfiktir .
Derleyicinin ayırıcısı bir şeyleri sadece yazmaçlar yerine bellekte depolamaya zorlandığında, bu dökülme olarak bilinir .
Bu tek bir işlemci talimatına mı indirgeniyor yoksa daha karmaşık mı?
Kesin olarak bildiğimiz tek şey Intel'in a push
ve bir pop
talimatı belgelediği , bu nedenle bunlar bu anlamda bir talimat.
Dahili olarak, biri değiştirmek, diğeri esp
bellek IO'yu yapmak için birden fazla mikrokoda genişletilebilir ve birden çok döngü alabilir.
Ancak push
daha spesifik olduğu için, tek bir komutun diğer komutların eşdeğer kombinasyonundan daha hızlı olması da mümkündür .
Bu çoğunlukla belgelenmiştir (der):
b
,w
,l
ya daq
bellek büyüklüğü manipüle göstermek için kullanılır. Ör:pushl %eax
vepopl %eax