x64 veremhasználat

Az RSP jelenlegi címén túli összes memória változékonynak minősül: Az operációs rendszer vagy hibakereső felülírhatja ezt a memóriát egy felhasználói hibakeresési munkamenet vagy egy megszakításkezelő során. Ezért az RSP-t mindig be kell állítani, mielőtt értékeket próbál meg beolvasni vagy beírni egy veremkeretbe.

Ez a szakasz a helyi változók veremterületének kiosztását és az alloka belső értékét ismerteti.

Veremfoglalás

A függvény prologja felelős a helyi változók, a mentett regiszterek, a veremparaméterek és a paraméterek veremterületének kiosztásáért.

A paraméterterület mindig a verem alján van (még akkor is, ha alloca használják), így minden függvényhívás során mindig a visszatérési címmel lesz szomszédos. Legalább négy bejegyzést tartalmaz, de mindig elegendő helyet a meghívható függvények által igényelt paraméterek tárolásához. Vegye figyelembe, hogy a regiszter paraméterek számára mindig van hely lefoglalva, még akkor is, ha maguk a paraméterek soha nem kerülnek a verembe; a hívott garantáltan minden paramétere számára le van foglalva a hely. A regiszter argumentumaihoz otthoni címek szükségesek, így egy összefüggő terület áll rendelkezésre, ha a hívott függvénynek az argumentumlista címét (va_list) vagy egy egyéni argumentumot kell felvennie. Ez a terület kényelmes helyet biztosít a regiszter argumentumok mentéséhez a thunk végrehajtása során, valamint hibakeresési lehetőségként (például megkönnyíti az argumentumok keresését a hibakeresés során, ha a prolog-kódban a saját címükön vannak tárolva). Még akkor is, ha a hívott függvény 4-nél kevesebb paramétert tartalmaz, a 4 veremhely ténylegesen a hívott függvény tulajdonában van, és a paraméterregisztrálási értékek mentésén kívül más célokra is használható. A hívó ezért nem tárolhat adatokat ennek a veremterületnek a mentén egy függvényhívás során.

Ha egy függvényben dinamikusan van lefoglalva (alloca) a tér, akkor egy nemvolatilis regisztert kell használni keretmutatóként a verem rögzített részének jelöléséhez, és ezt a regisztert menteni és inicializálni kell a prologban. Vegye figyelembe, hogy amikor alloca használatban van, ugyanazon hívótól ugyanazon hívottnak küldött hívások esetében regiszter paramétereik különböző otthoni címeket kaphatnak.

A verem mindig 16 bájtos igazítással lesz megtartva, kivéve a prologon belül (például a visszatérési cím leküldése után), és kivéve, ha ez külön meg van jelölve a függvénytípusok alatt egy bizonyos keretfüggvény osztály számára.

Az alábbiakban egy példa látható a veremelrendezésre, ahol az A függvény nem levélfüggvényt, B-t hív meg. Az A függvény prológja már lefoglalt helyet az összes, B által igényelt regiszter- és veremparaméter számára a verem alján. A hívás leküldi a visszatérési címet, a B prologja pedig helyet foglal le a helyi változók, a nemvolatilis regiszterek és a függvények hívásához szükséges tér számára. B használata esetén allocaa rendszer lefoglalja a helyet a helyi változó/nemvolatile regiszter mentési területe és a paraméterverem területe között.

Az x64-alapú konverziós példa veremelrendezésének diagramja.

Amikor a B függvény egy másik függvényt hív meg, a rendszer a visszatérési címet az RCX otthoni címe alatt küldi el.

Dinamikus paraméterveremterület felépítése

Ha egy keretmutató van használatban, akkor lehetőség van a paraméterveremterület dinamikus létrehozására. Ez jelenleg nem történik meg az x64 fordítóban.

Függvénytípusok

Alapvetően kétféle függvény létezik. A veremkeretet igénylő függvényeket keretfüggvénynek nevezzük. A veremkeretet nem igénylő függvényeket levélfüggvénynek nevezzük.

A keretfüggvények olyan függvények, amelyek lefoglalják a veremterületet, meghívnak más függvényeket, nemvolatilis regisztereket mentenek, vagy kivételkezelést használnak. Továbbá, egy függvénytábla-bejegyzésre is szükség van. A keretfüggvények prologot és epilogot igényelnek. A keretfüggvények dinamikusan lefoglalhatják a veremterületet, és keretmutatót is használhatnak. A keretfüggvények rendelkezésére áll ennek a hívási szabványnak a teljes képessége.

Ha egy keretfüggvény nem hív meg másik függvényt, akkor nem szükséges a verem igazítása (amelyre a szakaszveremfoglalás hivatkozik).

A levélfüggvény nem igényel függvénytáblázat-bejegyzést. Nem tud módosításokat végezni a nemvolatilis regisztereken, beleértve az RSP-t sem, ami azt jelenti, hogy nem tud függvényeket meghívni vagy lefoglalni a veremterületet. A végrehajtás során a verem kiegyenlítetlenül hagyható.

malloc igazítás

A malloc garantáltan olyan memóriát ad vissza, amely megfelelően van igazítva minden olyan objektum tárolásához, amely alapvető igazítással rendelkezik, és amely elfér a lefoglalt memória mennyiségében. Az alapvető igazítás olyan igazítás, amely kisebb vagy egyenlő a legnagyobb igazításnál, amelyet az implementáció támogat igazítási specifikáció nélkül. (A Microsoft C++-ban ez az igazítás szükséges egy double, vagy 8 bájthoz. A 64 bites platformokat megcélozó kódban ez 16 bájt.) Egy négy bájtos foglalás például egy négy bájtos vagy kisebb objektumot támogató határvonalhoz igazítható.

A Visual C++ lehetővé teszi a kiterjesztett igazítású, más néven túl igazított típusok típusok engedélyezését . Az SSE-típusok, mint például __m128 és __m256, valamint az olyan típusok, amelyek __declspec(align( n )) esetén n nagyobb, mint 8, kiterjesztett igazítással bírnak. A kiterjesztett igazítást igénylő objektumok számára megfelelő határvonalon a memória igazítása nincs garantálva a malloc által. A megfelelően igazított típusok memóriájának lefoglalásához használja a _aligned_malloc és a kapcsolódó függvényeket.

alloca (egy stack-memóriafoglaló függvény C nyelvben)

_alloca 16 bájtos igazítás szükséges, valamint a keretmutató használatához is szükséges.

A lefoglalt veremnek helyet kell tartalmaznia a később meghívott függvények paraméterei számára, ahogyan az a Veremfoglalás című részben is szerepel.

Lásd még

x64 szoftverkonvenciák
igazít
__declspec