Buradaki konular için daha fazla okuma: Linux Sistem Çağrıları için Kesin Kılavuz
Bunları Linux'ta GNU Assembler (gas) kullanarak doğruladım.
Çekirdek Arayüzü
x86-32 aka i386 Linux Sistem Çağrısı kuralı:
Linux için x86-32 parametreleri sistem çağrısı kayıtları kullanılarak geçirilir. %eax
syscall_number için. % ebx,% ecx,% edx,% esi,% edi,% ebp, sistem parametrelerine 6 parametre iletmek için kullanılır.
Dönüş değeri %eax
. Diğer tüm kayıtlar (EFLAGS dahil) genelinde korunur int $0x80
.
Aşağıdaki pasajı Linux Assembly Tutorial'dan aldım ama bundan şüpheliyim. Herhangi biri bir örnek gösterebilirse, harika olurdu.
Altıdan fazla bağımsız değişken varsa, bağımsız değişkenler
%ebx
listesinin depolandığı bellek konumunu içermelidir - ancak bunun için endişelenmeyin, çünkü altıdan fazla bağımsız değişken içeren bir sistem çağrısı kullanmanız pek olası değildir.
Örnek ve biraz daha fazla okuma için http://www.int80h.org/bsdasm/#alternate-calling-convention adresine bakın . İ386 Linux için bir Merhaba Dünya örneği int 0x80
: Merhaba, Linux sistem çağrıları ile montaj dilinde dünya?
32-bit sistem çağrıları yapmanın daha hızlı bir yolu vardır: kullanma sysenter
. Çekirdek sysenter
, dönüş adresini bulabilmesi için çekirdeğin işbirliği yapması gereken dansın kullanıcı alanı tarafı ile her işleme (vDSO) bir bellek sayfası eşler . Eşleştirme kayıt için Arg for ile aynıdır int $0x80
. Normalde sysenter
doğrudan kullanmak yerine vDSO'yu aramalısınız . ( VDSO'ya bağlanma ve çağrı yapma hakkında bilgi ve sistem çağrılarıyla ilgili diğer her şey hakkında daha fazla bilgi için Linux Sistem Çağrıları için Kesin Kılavuz'a bakın sysenter
.)
x86-32 [Ücretsiz | Açık | Net | DragonFly] BSD UNIX Sistemi Çağrı kuralı:
Parametreler yığına iletilir. Parametreleri (ilk itilen son parametre) yığına doğru itin. Sonra ek bir 32-bit kukla veri (Aslında kukla veri değil. Daha fazla bilgi için aşağıdaki bağlantıya bakın) ve sonra bir sistem çağrısı talimatı verinint $0x80
http://www.int80h.org/bsdasm/#default-calling-convention
x86-64 Linux Sistem Çağrısı kuralı:
x86-64 Mac OS X benzer ancak farklıdır . YAPILACAKLAR: * BSD'nin ne yaptığını kontrol et.
Bkz. Bölüm: Sistem V Uygulaması İkili Arayüz AMD64 Mimari İşlemci Eki "A.2 AMD64 Linux Çekirdek Kuralları" . İ386 ve x86-64 System V psABI'lerinin en son sürümlerini, bu sayfadan ABI bakımcının deposunda bulabilirsiniz . (Ayrıca bkz.x86 wiki'yi güncel ABI bağlantıları ve x86 asm ile ilgili diğer birçok iyi şey için etiketleyin.)
İşte bu bölümden snippet:
- Kullanıcı seviyesi uygulamaları,% rdi,% rsi,% rdx,% rcx,% r8 ve% r9 dizilerini geçmek için tamsayı kayıtları olarak kullanılır. Çekirdek arabirimi% rdi,% rsi,% rdx,% r10,% r8 ve% r9 kullanır.
syscall
Talimat ile bir sistem çağrısı yapılır . Bu % rcx ve% r11 clobbers yanı sıra% rax dönüş değeri, ancak diğer kayıtlar korunur.
- Sistem çağrısı sayısı% rax kaydında geçirilmelidir.
- Sistem çağrıları altı argümanla sınırlıdır, doğrudan yığına herhangi bir argüman iletilmez.
- Sistem çağrısından dönen% rax kaydı, sistem çağrısının sonucunu içerir. -4095 ile -1 arasındaki bir değer bir hatayı belirtir
-errno
.
- Çekirdeğe yalnızca INTEGER veya MEMORY sınıfı değerleri iletilir.
Bunun ABI için Linux'a özgü ekten olduğunu ve Linux için bile normatif değil bilgilendirici olduğunu unutmayın. (Ama aslında doğrudur.)
Bu 32 bit int $0x80
ABI , 64 bit kodda kullanılabilir (ancak kesinlikle önerilmez). 64 bit kodda 32 bit int 0x80 Linux ABI kullanırsanız ne olur? Hala girişlerini 32 bit olarak keser, bu nedenle işaretçiler için uygun değildir ve r8-r11'i sıfırlar.
Kullanıcı Arabirimi: işlev çağırma
x86-32 İşlev Çağırma kuralı:
X86-32'de parametreler yığına aktarıldı. Son parametre, tüm parametreler yapılana ve ardından call
talimat yürütülene kadar ilk önce yığına itildi . Bu, Linux'ta C kütüphanesi (libc) işlevlerini derlemeden çağırmak için kullanılır.
İ386 System V ABI'nin (Linux'ta kullanılır) modern sürümleri , x86-64 System V ABI'nin her zaman gerektirdiği gibi a'dan %esp
önce 16 baytlık hizalama call
gerektirir. Callees, bunu varsaymaya ve hizalanmamış arızalanan SSE 16 bayt yükleri / depoları kullanmasına izin verilir. Ancak tarihsel olarak, Linux sadece 4 bayt yığın hizalaması gerektiriyordu, bu nedenle 8 baytlık double
veya başka bir şey için bile doğal olarak hizalanmış alan ayırmak için ekstra iş gerekiyordu .
Bazı diğer modern 32-bit sistemler hala 4 bayttan fazla yığın hizalaması gerektirmez.
x86-64 Sistem V kullanıcı alanı İşlev Çağırma kuralı:
x86-64 Sistem V, kayıtları i386 Sistem V'in yığın bağımsız değişken kuralından daha verimli olan kayıtlara geçirir. Gecikmeleri ve değişkenleri belleğe (önbellek) depolamak ve daha sonra tekrar callee'ye yüklemek için ek talimatları önler. Bu, daha fazla kayıt olduğundan ve gecikmenin ve sıra dışı yürütmenin önemli olduğu modern yüksek performanslı CPU'lar için daha iyi olduğu için işe yarar. (İ386 ABI çok eskidir).
Bu yeni mekanizmada: İlk olarak parametreler sınıflara ayrılır. Her parametrenin sınıfı, çağrılan işleve aktarılma şeklini belirler.
Tam bilgi için bkz . Kısım olarak okuyan System V Uygulaması İkili Arabirim AMD64 Mimari İşlemci Eki'nin "3.2 İşlev Çağırma Dizisi" :
Bağımsız değişkenler sınıflandırıldıktan sonra, kayıtlar aşağıdaki gibi iletilmek üzere atanır (soldan sağa doğru):
- Sınıf HAFIZA ise, bağımsız değişkeni yığına iletin.
- Sınıf INTEGER ise,% rdi,% rsi,% rdx,% rcx,% r8 ve% r9 dizilerinin bir sonraki kullanılabilir kaydı kullanılır.
Böylece %rdi, %rsi, %rdx, %rcx, %r8 and %r9
, tamsayı / pointer (yani INTEGER sınıfı) parametrelerini derlemeden herhangi bir libc fonksiyonuna geçirmek için kullanılan kayıtlar da kullanılır. % rdi, ilk INTEGER parametresi için kullanılır. 2. için% rsi, 3. için% rdx vb. O zaman call
talimat verilmelidir. Yığın ( %rsp
) call
yürütüldüğünde 16B hizalı olmalıdır .
6'dan fazla INTEGER parametresi varsa, 7. INTEGER parametresi ve daha sonra yığına iletilir. (Arayan açılır, x86-32 ile aynı.)
İlk 8 kayan nokta değişkeni% xmm0-7 içinde, daha sonra yığın üzerinde geçirilir. Arama korumalı vektör kayıtları yok. (FP ve tamsayı bağımsız değişkenlerinin bir karışımına sahip bir işlev toplam 8'den fazla kayıt bağımsız değişkenine sahip olabilir.)
Değişken işlevler ( gibiprintf
) her zaman %al
= FP kayıt argümanlarının sayısına ihtiyaç duyar .
Yapıların ne zaman rdx:rax
bellekte kayıtlara ( dönüşte) paketleneceğine dair kurallar vardır . Ayrıntılar için ABI'ye bakın ve kodunuzun derleyicilere bir şeyin nasıl iletilmesi / döndürülmesi gerektiği konusunda hemfikir olduğundan emin olmak için derleyici çıktısını kontrol edin.
O Not Windows x64 fonksiyonu çağıran kongre gölge alanı gibi X86-64 Sistem V birden fazla önemli farklılıklar vardır gerekir (yerine kırmızı-bölgenin) arayan tarafından ayrılacak ve çağrı korunmuş xmm6-xmm15. Ve hangi argümanın hangi kayda girdiği çok farklı kurallar.