Windows64 neden x86-64'teki diğer tüm işletim sistemlerinden farklı bir çağrı kuralı kullanıyor?


110

AMD, x86-64'te kullanılacak arama kuralını açıklayan bir ABI belirtimine sahiptir. Kendi x86-64 çağrı kuralına sahip Windows dışında tüm işletim sistemleri bunu takip eder. Neden?

Bu farklılığın teknik, tarihsel veya politik nedenlerini bilen var mı yoksa bu tamamen bir NIHs sendromu meselesi mi?

Farklı işletim sistemlerinin daha yüksek seviyeli şeyler için farklı ihtiyaçları olabileceğini anlıyorum, ancak bu, örneğin Windows'ta yazmaç parametresinin rcx - rdx - r8 - r9 - rest on stackdiğer herkes kullanırken neden olduğunu açıklamıyor rdi - rsi - rdx - rcx - r8 - r9 - rest on stack.

Not: Bu arama kurallarının genel olarak nasıl farklılaştığının farkındayım ve gerekirse ayrıntıları nerede bulacağımı biliyorum. Bilmek istediğim şey neden .

Düzenleme: Nasıl yapılacağını öğrenmek için, örneğin wikipedia girişine ve oradaki bağlantılara bakın.


3
Pekala, sadece ilk kayıt için: rcx: ecx, msvc __thiscall x86 kuralı için "this" parametresiydi. Muhtemelen derleyicilerini x64'e taşımayı kolaylaştırmak için, ilk olarak rcx ile başladılar. O zaman diğer her şeyin de farklı olacağı, sadece bu ilk kararın bir sonucuydu.
Chris Becke

@Chris: Aşağıda AMD64 ABI ek belgesine (ve gerçekte ne olduğuna dair bazı açıklamalar) bir referans ekledim.
FrankH.

1
MS'den bir gerekçe bulamadım ama burada
phuclv

Yanıtlar:


81

X64'te dört bağımsız değişken kaydı seçme - UN * X / Win64 için ortak

X86 hakkında akılda tutulması gereken şeylerden biri, "kayıt numarası" kodlamasının yazmaç adının açık olmamasıdır; talimat kodlaması açısından ( MOD R / M baytı, bkz. http://www.c-jump.com/CIS77/CPU/x86/X77_0060_mod_reg_r_m_byte.htm ), kayıt numaraları 0 ... 7 - bu sırayla - ?AX, ?CX, ?DX, ?BX, ?SP, ?BP, ?SI, ?DI.

Dolayısıyla, dönüş değeri için A / C / D'yi (regs 0..2) ve ilk iki argümanı ("klasik" 32 bitlik kuraldır) seçmek __fastcallmantıklı bir seçimdir. 64bit'e gitme söz konusu olduğunda, "daha yüksek" kayıtlar sipariş edilir ve hem Microsoft hem de UN * X / Linux ilk olanlar için R8/ R9olarak gitti .

Bunu göz önüne aldığımızda tutulması, Microsoft'un seçimi RAX(dönüş değeri) ve RCX, RDX, R8, R9(arg [0..3]) seçerseniz anlaşılabilir bir seçim vardır dört argümanlar için kayıtlar.

AMD64 UN * X ABI'nin neden daha RDXönce seçtiğini bilmiyorum RCX.

X64'te altı bağımsız değişken kaydı seçme - UN * X'e özgü

RISC mimarilerinde UN * X, geleneksel olarak kayıtlarda geçen argümanları - özellikle ilk altı argüman için (en azından PPC, SPARC, MIPS'de böyledir) yapmıştır. AMD64 (UN * X) ABI tasarımcılarının bu mimaride de altı kayıt kullanmayı seçmelerinin ana nedenlerinden biri bu olabilir.

Yani isterseniz altı bağımsız değişkenleri geçmesine kayıtları ve seçim için mantıklı RCX, RDX, R8ve R9dördü için iki başka hangi almalı?

"Daha yüksek" regler, onları seçmek için ek bir talimat ön ek baytı gerektirir ve bu nedenle daha büyük bir komut boyutu ayak izine sahiptir, bu nedenle seçenekleriniz varsa bunlardan herhangi birini seçmek istemezsiniz. Klasik kayıtlardan, örtük anlamı nedeniyle RBPve RSPbunlar mevcut değildir ve RBXgeleneksel olarak, AMD64 ABI tasarımcılarının gereksiz yere uyumsuz olmak istemediği UN * X (global ofset tablosu) üzerinde özel bir kullanımı vardır.
Ergo, tek seçenek vardı RSI/ RDI.

Öyleyse , argüman yazmaçlarını RSI/ RDIolarak almanız gerekiyorsa, bunlar hangi argümanlar olmalıdır?

Bunları yapmak arg[0]ve arg[1]bazı avantajları vardır. CHao'nun yorumuna bakın.
?SIve ?DIdize talimatı kaynağı / hedef işlenenleridir ve cHao'nun da bahsettiği gibi, argüman kayıtları olarak kullanımları, AMD64 UN * X arama kurallarıyla mümkün olan en basit strcpy()işlevin yalnızca iki CPU talimatından oluştuğu anlamına gelir, repz movsb; retçünkü kaynak / hedef adresler arayan tarafından doğru kayıtlara yerleştirilmiştir. Özellikle düşük seviyeli ve derleyici tarafından üretilen "yapıştırıcı" kodunda (örneğin, bazı C ++ yığın ayırıcılarının yapım sırasında sıfır dolduran nesneleri veya çekirdeğin sıfır dolduran yığın sayfalarını düşünün.sbrk()veya yazma üzerine kopyalama sayfa hataları) muazzam miktarda blok kopyalama / doldurma, bu nedenle bu tür kaynak / hedef adres bağımsız değişkenlerini "doğru" kayıtlar.

Yani bir bakıma, BM * X ve Win64 BM * X "prepends" iki ek argümanlar, kasten seçilmiş içinde sadece farklıdır RSI/ RDIkayıtları, dört bağımsız değişken doğal seçim RCX, RDX, R8ve R9.

Onun ötesinde ...

UN * X ve Windows x64 ABI'leri arasında, argümanların belirli kayıtlara eşlenmesinden daha fazla fark vardır. Win64'e genel bakış için, kontrol edin:

http://msdn.microsoft.com/en-us/library/7kcdt6fy.aspx

Win64 ve AMD64 UN * X, yığın alanının kullanım şekli açısından da çarpıcı biçimde farklılık gösterir; Win64 üzerinde, örneğin, arayan gerekir hatta args 0 ... 3 kayıtlarında geçirilen rağmen fonksiyon argümanlar için stackspace tahsis. Öte yandan, UN * X'te, bir yaprak işlevinin (yani, diğer işlevleri çağırmayan), 128 Bayttan fazlasına ihtiyaç duymuyorsa yığın alanı ayırması bile gerekmez (evet, sahipsiniz ve kullanabilirsiniz belirli miktarda yığın ayırmadan ... pekala, çekirdek kodu değilseniz, şık hataların kaynağı). Tüm bunlar belirli optimizasyon seçimleridir, bunların çoğu için mantık, orijinal posterin wikipedia referansının işaret ettiği tam ABI referanslarında açıklanmıştır.


1
Kayıt adları hakkında: Bu önek baytı bir faktör olabilir. Ama sonra MS için argüman kayıtları olarak rcx - rdx - rdi - rsi'yi seçmesi daha mantıklı olacaktır. Ancak, sıfırdan bir ABI tasarlıyorsanız, ilk sekizin sayısal değeri size rehberlik edebilir, ancak mükemmel derecede iyi bir ABI zaten mevcutsa, onları değiştirmek için hiçbir neden yoktur, bu yalnızca daha fazla kafa karışıklığına yol açar.
JanKanis

2
RSI / RDI'da: Bu talimatlar genellikle satır içi olacaktır, bu durumda çağrı kuralı önemli değildir. Aksi takdirde, sistem genelinde bu işlevin yalnızca bir kopyası (veya belki birkaç kopyası) vardır, bu nedenle toplamda yalnızca bir avuç bayt tasarrufu sağlar . Değmez. Diğer farklılıklar / çağrı yığını hakkında: Belirli seçimlerin kullanışlılığı ABI referanslarında açıklanmıştır, ancak bir karşılaştırma yapmazlar. Neden diğer optimizasyonların seçilmediğini söylemiyorlar - örneğin neden Windows 128 baytlık kırmızı bölgeye sahip değil ve AMD ABI neden argümanlar için ekstra yığın yuvalarına sahip değil?
JanKanis

1
@cHao: hayır. Ama yine de değiştirdiler. Win64 ABI, Win32'den farklıdır (ve uyumlu değildir) ve ayrıca AMD ABI'den farklıdır.
JanKanis

8
@Somejan: Win64 ve Win32 __fastcall, 32bit'ten büyük olmayan ikiden fazla argüman içermeyen ve 32bit'ten büyük olmayan bir değer döndüren durumlarda% 100 aynıdır. Bu küçük bir işlev sınıfı değil. İ386 / amd64 için UN * X ABI'ler arasında böyle bir geriye dönük uyumluluk mümkün değildir.
FrankH.

2
@szx: Kasım 2000'den itibaren ilgili posta listesi başlığını buldum ve gerekçesini özetleyen bir yanıt gönderdim. Bunun memcpybu şekilde uygulanabileceğini unutmayın , değil strcpy.
Peter Cordes

42

IDK, Windows'un yaptıklarını neden yaptı? Bir tahmin için bu cevabın sonuna bakın. SysV çağrı sözleşmesinin nasıl kararlaştırıldığını merak ediyordum, bu yüzden posta listesi arşivine girdim ve bazı düzgün şeyler buldum.

AMD mimarları üzerinde aktif olduğu için AMD64 e-posta listesindeki bu eski başlıklardan bazılarını okumak ilginç. Örneğin, kayıt adlarının seçilmesi zor kısımlardan biriydi: AMD , orijinal 8 yazmacı r0-r7'yi yeniden adlandırmayı veya yeni yazmaçları şöyle çağırmayıUAX düşündü .

Ayrıca, çekirdek geliştiricilerinden gelen geri bildirimler, orijinal tasarımı syscallve swapgskullanılamaz hale getiren şeyleri belirledi . AMD , herhangi bir gerçek yonga yayınlamadan önce bunu çözmek için talimatı bu şekilde güncelledi . 2000 yılının sonlarında Intel'in muhtemelen AMD64'ü benimsemeyeceği varsayımı da ilginçtir.


SysV (Linux) çağrı kuralı ve kaç kaydın arayanın korunmasına karşı kaç kaydın aranarak kurtarılacağına dair karar, ilk olarak Kasım 2000'de Jan Hubicka (bir gcc geliştiricisi) tarafından yapıldı. O SPEC2000 derlenmiş ve kod boyutu ve komutların sayısına baktım. Bu tartışma dizisi, bu GY sorusuyla ilgili cevaplar ve yorumlarla aynı fikirlerin bazıları etrafında dönüyor. 2. bir iş parçacığında, mevcut diziyi en uygun ve umarız son olarak önerdi ve bazı alternatiflerden daha küçük kodlar üretti .

"Genel" terimini, kullanılıyorsa itilmesi / çıkarılması gereken çağrı korumalı kayıtları kastetmek için kullanıyor.

Seçimi rdi, rsi, rdxilk üç bağımsız değişken tarafından motive edilmiş olarak:

  • memsetbağımsız değişkenlerinde C dizesi işlevini çağıran işlevlerde küçük kod boyutu tasarrufu (gcc, bir rep dizesi işlemini satır içine alır?)
  • rbxREX önekleri (rbx ve rbp) olmadan erişilebilen iki çağrı korumalı reg'e sahip olmak bir kazançtır çünkü çağrı korumalıdır. Muhtemelen, herhangi bir talimat tarafından dolaylı olarak kullanılmayan diğer tek kural olduğu için seçilmiştir. (rep string, shift count ve mul / div çıktıları / girdileri diğer her şeye dokunur).
  • Özel amaçlı yazmaçların hiçbiri çağrı korumalı değildir (önceki noktaya bakın), bu nedenle rep dizesi komutlarını veya değişken sayı kaydırmasını kullanmak isteyen bir işlev, işlev argümanlarını başka bir yere taşımak zorunda kalabilir, ancak / arayanın değerini geri yükleyin.
  • EAX gibi özel amaçlar için yaygın olarak kullanılan kayıt olduğundan, dizinin başlarında RCX'ten kaçınmaya çalışıyoruz, bu nedenle dizide eksik olması aynı amaca sahiptir. Ayrıca, sistem çağrıları için kullanılamaz ve mümkün olduğunca işlev çağrı sırasına uyacak şekilde sistem çağrı dizisi yapmak istiyoruz.

    (arka plan: syscall/ sysretkaçınılmaz imha rcx(ile rip) ve r11(ile RFLAGSçekirdek başlangıçta ne olduğunu göremiyorum bu yüzden,) rcxne zaman syscallran.)

Çekirdek sistem çağrısı ABI, ABI işlev çağrısı ile eşleşecek şekilde seçilmiştir, r10bunun yerine rcxbir libc sarmalayıcı mmap(2)can just mov %rcx, %r10/ mov $0x9, %eax/ gibi çalışır syscall.


İ386 Linux tarafından kullanılan SysV çağrı kuralı, Window 32bit __vectorcall ile karşılaştırıldığında berbattır. Yığın üzerindeki her şeyi edx:eaxaktarır ve küçük yapılar için değil, yalnızca int64 için döner . Uyumluluğunu sürdürmek için çok az çaba harcanması şaşırtıcı değil. Bunu yapmamak için bir neden olmadığında rbx, orijinal 8'de (REX önekine ihtiyaç duymayan) bir başkasına sahip olmanın iyi olduğuna karar verdikleri için çağrıyı korumalı tutmak gibi şeyler yaptılar.

ABI'yı optimum hale getirmek, uzun vadede diğer tüm düşüncelerden çok daha önemlidir. Bence oldukça iyi bir iş çıkardılar. Farklı kayıtlardaki farklı alanlar yerine kayıtlara paketlenmiş yapıları döndürmek konusunda tam olarak emin değilim. Sanırım tarlalarda gerçekten işlem yapmadan onları değerine göre geçiren kod bu şekilde kazanır, ancak fazladan paket açma işi aptalca görünüyor. Daha fazla tamsayı dönüş rdx:raxyazmacıları olabilirdi, bu yüzden 4 üyeli bir yapıyı döndürmek onları rdi, rsi, rdx, rax veya başka bir şekilde döndürebilirdi.

SSE2 tamsayılar üzerinde çalışabildiğinden, tamsayıları vektör reglerinde geçirmeyi düşündüler. Neyse ki bunu yapmadılar. Tam sayılar, işaretçi ofsetleri olarak çok sık kullanılır ve belleği yığınlamak için bir gidiş dönüş oldukça ucuzdur . Ayrıca SSE2 komutları, tamsayı komutlarından daha fazla kod baytı alır.


Windows ABI tasarımcılarının, asm'yi birinden diğerine aktarması gereken veya #ifdefbazı ASM'lerde birkaç s kullanabilen kişilerin yararına 32 ve 64 bit arasındaki farkları en aza indirmeyi hedeflediklerinden şüpheleniyorum, böylece aynı kaynak daha kolay bir şekilde oluşturulabilir. bir işlevin 32 veya 64 bit sürümü.

Araç zincirindeki değişiklikleri en aza indirmek pek olası görünmüyor. Bir x86-64 derleyicisinin, yazmacının ne için kullanıldığını ve çağırma kuralının ne olduğunu gösteren ayrı bir tabloya ihtiyacı vardır. 32 bit ile küçük bir örtüşmeye sahip olmanın, araç zinciri kod boyutu / karmaşıklığında önemli tasarruflar sağlama olasılığı düşüktür.


1
Sanırım, Raymond Chen'in blogunda, MS tarafından kıyaslama yaptıktan sonra bu kayıtları seçmenin gerekçesini okudum ama artık bulamıyorum. Ancak, ana bölge ile ilgili bazı nedenler burada açıklanmıştır blogs.msdn.microsoft.com/oldnewthing/20160623-00/?p=93735 blogs.msdn.microsoft.com/freik/2006/03/06/…
phuclv


@phuclv: Ayrıca bakınız ESP'nin altında yazmak geçerli midir? . Raymond'ın cevabıma ilişkin yorumları, x86 32/64 Windows'un neden şu anda fiili bir kırmızı bölgeye sahip olmadığını açıklayan, bilmediğim bazı SEH ayrıntılarına işaret etti. Blog gönderisinde, bu yanıtta bahsettiğim aynı kod sayfası işleyici olasılığı için bazı makul durumlar var :) Yani evet, Raymond bunu açıklamakta benden daha iyi bir iş çıkardı (şaşırtıcı olmayan bir şekilde, çünkü Windows hakkında çok az şey bilmeye başladım), ve x86 olmayanlar için kırmızı bölge boyutları tablosu gerçekten düzgün.
Peter Cordes

13

Microsoft'un başlangıçta "AMD64'ün ilk çabalarına resmi olarak bağlı olmadığını" ( Matthew Kerner ve Neil Padgett'in "A History of Modern 64-bit Computing" kitabından), çünkü Intel ile IA64 mimarisi üzerinde güçlü ortaklar olduğunu unutmayın. Bence bu, GCC mühendisleri ile hem Unix hem de Windows üzerinde kullanmak üzere bir ABI üzerinde çalışmaya açık olsalar bile, bunu yapmayacakları anlamına geliyordu, çünkü olmadıklarında AMD64 çabasını halka açık bir şekilde desteklemek anlamına geliyordu '' Henüz resmi olarak yapılmadı (ve muhtemelen Intel'i alt üst ederdi).

Bunun da ötesinde, o günlerde Microsoft'un açık kaynak projelerle dost olma yönünde kesinlikle hiçbir eğilimi yoktu. Kesinlikle Linux veya GCC değil.

Öyleyse neden bir ABI üzerinde işbirliği yapsınlar? ABI'lerin farklı olduğunu tahmin ediyorum çünkü aşağı yukarı aynı anda ve tek başına tasarlandılar.

"A History of Modern 64-bit Computing" den bir başka alıntı:

Microsoft işbirliğine paralel olarak AMD, çipe hazırlanmak için açık kaynak topluluğunu da meşgul etti. AMD, alet zinciri çalışması için hem Code Sorcery hem de SuSE ile sözleşme yaptı (Red Hat, Intel tarafından IA64 araç zinciri bağlantı noktasında zaten çalışıyordu). Russell, SuSE'nin C ve FORTRAN derleyicileri ürettiğini ve Code Sorcery'nin bir Pascal derleyicisi ürettiğini açıkladı. Weber, şirketin bir Linux bağlantı noktası hazırlamak için Linux topluluğuyla da meşgul olduğunu açıkladı. Bu çaba çok önemliydi: Microsoft için AMD64 Windows çabasına yatırım yapmaya devam etmesi için bir teşvik görevi gördü ve aynı zamanda o sırada önemli bir işletim sistemi haline gelen Linux'un yongalar piyasaya sürüldüğünde kullanılabilir olmasını sağladı.

Weber, Linux çalışmasının AMD64'ün başarısı için kesinlikle çok önemli olduğunu söyleyecek kadar ileri gitti, çünkü AMD'nin gerekirse başka şirketlerin yardımı olmadan uçtan uca bir sistem üretmesini sağladı. Bu olasılık, AMD'nin diğer ortaklar geri çekilse bile en kötü durumda hayatta kalma stratejisine sahip olmasını sağladı ve bu da diğer ortakları geride bırakılma korkusuyla meşgul etti.

Bu, AMD'nin bile MS ve Unix arasındaki işbirliğinin zorunlu olarak en önemli şey olduğunu düşünmediğini, ancak Unix / Linux desteğine sahip olmanın çok önemli olduğunu gösteriyor. Belki bir veya iki tarafı uzlaşmaya veya işbirliği yapmaya ikna etmeye çalışmak, ikisini de rahatsız etme çabasına veya riskine (?) Değmez miydi? Belki de AMD, ortak bir ABI önermenin bile, çip hazır olduğunda yazılım desteğinin hazır olması gibi daha önemli bir hedefi geciktirebileceğini veya rayından çıkarabileceğini düşündü.

Benim açımdan spekülasyon, ancak ABI'lerin farklı olmasının ana nedeni, MS ve Unix / Linux taraflarının birlikte çalışmamasının politik nedeniydi ve AMD bunu bir sorun olarak görmedi.


Siyasete güzel bir bakış açısı. Bunun AMD'nin hatası veya sorumluluğu olmadığını kabul ediyorum. Daha kötü bir arama kuralı seçtiği için Microsoft'u suçluyorum. Çağrı gelenekleri daha iyi hale gelmiş olsaydı, biraz sempati duyardım, ancak başlangıçtaki ABI'larından , yığından __vectorcallgeçmek kötü olduğu için değişmeleri gerekiyordu __m128. Vektör gruplar gruplar bazı düşük 128b çağrısı korunmuş anlambilim olması (. Genişletilebilir kaydetme / değil AVX ile hala orijinal olarak SSE ile geri yükleme mekanizmasını ve tasarımı için değil kısmen Intel'in arızası) da garip
Peter Cordes

1
ABI'lerin ne kadar iyi olduğuna dair hiçbir uzmanlığım veya bilgim yok . Sadece arada sırada ne olduklarını bilmem gerekiyor, böylece montaj düzeyinde anlayabilirim / hata ayıklayabilirim.
Michael Burr

1
İyi bir ABI, kod boyutunu ve talimat sayısını en aza indirir ve bellek üzerinden fazladan gidiş gelişlerden kaçınarak bağımlılık zincirlerini düşük gecikmeli tutar. (argümanlar veya dökülmesi / yeniden yüklenmesi gereken yereller için). Takas var. SysV'nin kırmızı bölgesi, bir miktar çizik alanı elde etmek için yığın işaretçisini ayarlamak zorunda kalmama gibi yaprak işlevleri için nispeten büyük bir fayda sağlamak üzere bir yerde (çekirdeğin sinyal işleyici dağıtıcısı) birkaç ekstra talimat alır. Yani bu, sıfıra yakın dezavantajlı net bir kazanç. SysV için önerildikten sonra neredeyse hiç tartışılmadan kabul edildi.
Peter Cordes

1
@dgnuff: Doğru, çekirdek kodu neden Red Zone kullanamıyor? sorusunun cevabı bu . Kesmeler, CPU kullanıcı alanı kodunu çalıştırırken ulaşsalar bile, kullanıcı alanı yığınını değil çekirdek yığınını kullanır. Çekirdek, kullanıcı alanı yığınlarına güvenmez çünkü aynı kullanıcı alanı sürecindeki başka bir iş parçacığı onu değiştirebilir ve böylece çekirdeğin kontrolünü ele geçirebilir!
Peter Cordes

1
@ DavidA.Gray: evet, ABI sen demiyor sahip optimize kod genellikle değil bu yüzden bir çerçeve işaretçi olarak RBP kullanmak (fonksiyonlar dışında kullanımının allocaya da birkaç diğer durumlar). gcc -fomit-frame-pointerLinux'ta varsayılan olmaya alışkınsanız bu normaldir . ABI, istisna işlemenin çalışmaya devam etmesine izin veren yığın çözme meta verilerini tanımlar. (GNU / Linux x86-64 System V'nin CFI öğelerinde olduğu gibi çalıştığını varsayıyorum .eh_frame). gcc -fomit-frame-pointersonsuza kadar x86-64'te varsayılan (optimizasyon etkin) ve diğer derleyiciler (MSVC gibi) aynı şeyi yapıyor.
Peter Cordes

12

Win32'nin ESI ve EDI için kendi kullanımları vardır ve bunların değiştirilmemesini (veya en azından API çağrılmadan önce geri yüklenmelerini) gerektirir. 64 bit kodun RSI ve RDI ile aynı şeyi yaptığını hayal ediyorum, bu da neden işlev argümanlarını iletmek için kullanılmadıklarını açıklıyor.

Yine de RCX ve RDX'in neden değiştirildiğini size söyleyemem.


1
Tüm arama kurallarında bazı kayıtlar çizik olarak belirlenmiş ve bazıları da Win64'teki ESI / EDI ve RSI / RDI gibi korunmuş olarak belirtilmiştir. Ancak bunlar genel amaçlı kayıtlardır, Microsoft bunları farklı şekilde kullanmayı sorunsuz bir şekilde seçebilirdi.
JanKanis

1
@Somejan: Elbette, tüm API'yi yeniden yazmak ve iki farklı işletim sistemine sahip olmak istiyorlarsa. Yine de buna "problemsiz" demezdim. MS onlarca yıldır, x86 kayıtlarıyla ne yapıp ne yapmayacağına dair belirli sözler verdi ve tüm bu süre boyunca az çok tutarlı ve uyumlu oldular. Sırf AMD'nin bir fermanı yüzünden, özellikle de bu kadar keyfi ve "işlemci oluşturma" alanının dışında kalan bir ferman yüzünden tüm bunları camdan atmayacaklar.
cHao

5
@Somejan: AMD64 UN * X ABI her zaman tam olarak böyleydi - UNIX'e özgü bir parça. X86-64.org/documentation/abi.pdf belgesinin başlığı , bir nedenden ötürü System V Application Binary Interface, AMD64 Architecture Processor Supplement olarak adlandırılmıştır. (Ortak) UNIX ABI'leri (çok hacimli bir koleksiyon, sco.com/developers/devspecs ) , belirli bir işlemci için işlev çağıran kurallar ve veri düzeni kuralları olan işlemciye özgü bölüm 3 - Ek - için bir bölüm bırakır .
FrankH.

7
@Somejan: Microsoft Windows hiçbir zaman özellikle UN * X'e yakın olma girişiminde bulunmadı ve konu Windows'u x64 / AMD64'e taşımaya geldiğinde, kendi __fastcall arama kurallarını genişletmeyi seçtiler . Sen Win32 / Win64 uyumlu değildir iddia ama sonra yakından bak: alan bir fonksiyon için iki 32bit args ve getiri 32bit, Win64 ve Win32 __fastcallaslında olan % 100 uyumlu (iki 32bit args, aynı dönüş değeri geçen aynı regs). Hatta bazı ikili (!) Kodlar her iki işletim modunda da çalışabilir. UNIX tarafı "eski yöntemlerle" tamamen koptu. İyi nedenlerden ötürü, ancak mola bir mola demektir.
FrankH.

2
@Olof: Bu bir derleyici şeyinden daha fazlası. NASM'de bağımsız işler yaptığımda ESI ve EDI ile ilgili sorunlar yaşadım. Windows bu kayıtları kesinlikle önemsiyor. Ama evet, bunları yapmadan önce kaydederseniz ve Windows ihtiyaç duymadan önce geri yüklerseniz kullanabilirsiniz.
cHao
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.