ARM Exception Handling
Systém Windows na ARM používá stejnou výjimku strukturovaného zpracování mechanismus pro asynchronní generovaný hardwaru a synchronní generovaný softwaru výjimek.Obslužné rutiny výjimek konkrétní jazyk jsou vytvořeny na základě s použitím jazyka pomocné funkce pro zpracování výjimek na strukturovaného systému Windows.Tento dokument popisuje zpracování výjimek v systému Windows na ARM a pomocníky jazyk používaný kód, který je generován MASM a kompilátor Visual C++.
Zpracování výjimek ARM
Systém Windows na ARM používá odvíjejí kódy k řízení zásobníku unwind během structured exception handling (SEH).Odvíjejí kódy jsou sekvenci bajtů, které jsou uloženy v sekci .xdata spustitelného souboru obrázku.Operace kódu prologu a epilogu funkce popisují abstraktní způsobem tak, aby účinky prologu funkce mohou být vráceny zpět k přípravě unwind do zásobníku volajícího.
EABI ARM (binární rozhraní vložený aplikace) určuje unwinding modelu výjimky, která používá odvíjejí kódy, ale není dostatečné pro SEH unwind v systému Windows, který musí zpracovat asynchronní případy, kdy procesor uprostřed prologu nebo epilogu funkce.Systém Windows také odděluje do unwind úroveň funkci a unwind konkrétní jazyk oboru, unwinding prvek, který je jednotný v ARM EABI.Z těchto důvodů se systému Windows na ARM Určuje další podrobnosti o unwinding dat a postup.
Předpoklady
Spustitelné bitové kopie systému Windows na ARM použijte formát přenosných spustitelné soubory (PE).Další informace naleznete v tématu Microsoft PE a COFF specifikace.Informace zpracování výjimek je uložen v částech .pdata a .xdata obrázku.
Mechanismus zpracování výjimek provádí některé předpoklady o kód, který následuje ABI pro systém Windows na ARM:
Když dojde k výjimce v těle funkce, není důležité, zda operace prologu jsou vráceny, nebo epilogu operace jsou prováděny vpřed způsobem.Oba musí mít identické výsledky.
Prologů a epilogů často vzájemně zrcadlí.To lze zmenšit velikost metadat potřebné k popisu unwind.
Funkce jsou obvykle relativně malé.Několik optimalizací tedy spoléhat na to pro efektivní balení data.
Pokud podmínka je umístěn na epilogu, platí rovnoměrně pro každou instrukci v epilogu.
Pokud ukazatel na zásobník (SP) je uložen v jiné registru v prologu, který musí zůstat registrovat beze změny prostřednictvím funkce, tak, aby kdykoli lze obnovit původní poskytovatele služeb.
Není-li SP je uložen v jiné registrovat všechny manipulaci se musí vyskytovat výhradně v rámci prologu a epilogu.
Chcete-li odvíjejí jakékoli zásobníku, jsou požadovány tyto operace:
Upravit r13 (SP) v krocích 4 bajtů.
Automatické skrytí jednu nebo více celočíselné registry.
Automatické skrytí jeden nebo více VFP (virtuální s plovoucí desetinnou čárkou) zaregistruje.
Zkopírujte hodnotu libovolného registrovat r13 (SP).
Načíst poskytovatele služeb pomocí malé operace po snížení hodnoty ze zásobníku.
Analyzovat jeden z typů několik dobře definovaný rámec.
.pdata záznamů
Záznamy .pdata PE formát obrázku jsou seřazený pole pevné velikosti položek, které popisují každé funkce manipulovat s zásobníku.Funkce listu, které jsou funkce, které nevyžadují další funkce, nevyžaduje .pdata záznamů při jejich nechcete pracovat s zásobníku.(To znamená, jejich nevyžaduje žádné místní úložiště a nemáte k dispozici pro uložení nebo obnovení nezávislé registry.).Záznamy pro tyto funkce lze vynechat z části .pdata uložit místa.Operace unwind z jednoho z těchto funkcí můžete jednoduše zkopírujete zpáteční adresa z odkaz registrovat (LR) na čítač programu (PC) až po volajícího.
Každý záznam .pdata pro ARM je dlouhý 8 bajtů.Obecný formát záznamu umístí relativní virtuální adresa (RVA) zahájení funkce v první slovo 32-bit následovaný druhý slovo, které obsahuje ukazatel na .xdata proměnné délky bloku nebo sbalené slovo, které popisuje unwinding posloupnost kanonické funkce, jak je znázorněno v této tabulce:
Posun aplikace Word |
Bity |
Účel |
---|---|---|
0 |
0-31 |
Function Start RVAje 32-bit RVA zahájení funkce.Pokud je funkce obsahuje kód jezdce, musí být nastavena nízká bit tuto adresu. |
1 |
0-1 |
Flagje 2-bit pole, která určuje, jak interpretovat zbývající 30 bitů druhý .pdata slova.Pokud Flag je 0, pak zbývající bity formuláře Exception Information RVA (s nízkým dva bity implicitně 0).Pokud Flag je nulová, pak zbývající bity formuláře Packed Unwind Data struktury. |
1 |
2-31 |
Exception Information RVAor Packed Unwind Data. Exception Information RVApředstavuje adresu strukturu proměnné délky výjimky informace uložené v části .xdata.Tato data musí být zarovnáno 4 bajtů. Packed Unwind Dataje nutné komprimovaný popis operací odvíjejí z funkce, za předpokladu, že kanonické formuláře.V takovém případě je třeba zadat žádný záznam .xdata. |
Zabaleny odvíjejí dat
Data lze použít pro funkce jehož prologů a epilogů postupujte kanonického tvaru popsané níže, zabaleny odvíjejí.Tím se eliminuje potřeba záznam .xdata a významně snižuje použitý prostor povinným údajem odvíjejí data.Kanonické prologů a epilogů jsou určeny k požadavkům na běžné jednoduché funkce, která nevyžaduje obslužná rutina výjimky a provede její instalaci a jejich vyřazování z provozu operace standardní pořadí.
Tato tabulka zobrazuje ve formátu aplikace .pdata záznam, který má zabaleny odvíjejí dat:
Posun aplikace Word |
Bity |
Účel |
---|---|---|
0 |
0-31 |
Function Start RVAje 32-bit RVA zahájení funkce.Pokud je funkce obsahuje kód jezdce, musí být nastavena nízká bit tuto adresu. |
1 |
0-1 |
Flagje 2-bit pole, které má tyto význam:
|
1 |
2-12 |
Function Lengthje pole 11-bit poskytující délku celého funkce v bajtech dělené 2.Pokud je větší než 4 kB funkce, musí záznam úplná .xdata namísto něho použit. |
1 |
13-14 |
Retje 2-bit pole, která určuje, jak vrátí funkce:
|
1 |
15 |
Hje 1-bit příznak, který určuje, zda funkce "homes" celočíselný parametr zaregistruje (r0-r3) zobrazením na začátku funkce a před vrácením zruší přidělení 16 bajtů zásobníku.(0 = není domácí registrů, 1 = domácnosti Registry.) |
1 |
16-18 |
Reg3-bit pole, která značí index posledního uložena stálé registru.Pokud R bit je 0, pak pouze celočíselných registrech jsou ukládány a jsou považovány za v rozsahu od r4 rN, kde N je rovno 4 + Reg.Pokud R bit je 1 a potom pouze s plovoucí desetinnou čárkou registry jsou ukládány a jsou považovány za v rozsahu od d8 – rozlišující název, kde N je rovno 8 + Reg.Speciální kombinace R = 1 a Reg = 7 označuje, že jsou uložit žádné registrů. |
1 |
19 |
Rje 1-bit příznak, který určuje, zda jsou uloženém nezávislé registry celočíselné registry (0) nebo s plovoucí desetinnou čárkou registrů (1).Pokud R je nastavena na hodnotu 1 a hodnota parametru Reg je nastaveno na 7, byly přesunuty žádné nezávislé registry. |
1 |
20 |
Lje 1-bit příznak, který určuje, zda funkce uloží a obnovování LR, spolu s jinými registry indikován Reg pole.(0 = není uložit nebo obnovit, 1 = neposkytuje uložit nebo obnovit.) |
1 |
21 |
Cje 1-bit příznak, který určuje, zda funkce obsahuje doplňující pokyny k nastavení řetězci rámec pro rychlé zásobník procházení (1), nebo ne (0).Pokud je tento bit nastaven, r11 je implicitně přidán do seznamu celé číslo nezávislé registry uložen.(Naleznete v tématu omezení pod if C příznak se používá.) |
1 |
22-31 |
Stack Adjustje 10-bit pole, které označuje počet bajtů zásobníku, které byly přiděleny pro tuto funkci, dělené 4.Však pouze hodnoty mezi hodnotu 0x000 0x3F3 mohou být přímo kódovaná v řetězci.Funkce, které přidělit více než 4044 bajtů zásobníku musí používat úplný .xdata záznamu.Pokud Stack Adjust pole je 0x3F4 nebo větší, pak nízké 4 bitů mít speciální význam:
|
Z důvodu možné redundanci v kódování vyšší než tato omezení platí:
Pokud C příznak je nastaven na hodnotu 1:
L Příznak musí být nastavena na hodnotu 1, také, protože rámec řetězení požadované r11 a LR.
R11 nesmí být zahrnuty v sadě registrů popsaného Reg.To znamená, je-li r4 r11 odesílají, Reg by měla pouze popisují r4 r10, protože C příznak znamená r11.
Pokud Ret pole je nastaven na hodnotu 0, L příznak musí být nastavena na hodnotu 1.
Porušení těchto omezení způsobí, že nepodporovaný sekvence.
Pro účely diskuse níže dva pseudo příznaky jsou odvozeny od Stack Adjust:
PFnebo "prologu skládání" znamená, že Stack Adjust 0x3F4 nebo je nastavený větší a bit 2.
EFnebo "epilogu skládání" znamená, že Stack Adjust 0x3F4 nebo je nastavený větší a bit 3.
Prologů pro kanonické funkce mohou mít maximálně 5 pokyny (Všimněte si, že se vzájemně vylučují 3a a 3b):
Instrukce |
OpCode předpokládá přítomen, je-li: |
Velikost |
OpCode |
Odvíjejí kódy |
---|---|---|---|---|
1 |
H==1 |
16 |
push {r0-r3} |
04 |
2 |
C== 1 nebo L== 1 nebo R== 0 nebo PF == 1 |
16/32 |
push {registers} |
80-BF/D0-SV/ES ED |
3a |
C== 1 a (L== 0 a R== 1 a PF == 0) |
16 |
mov r11,sp |
C0-CR/FB |
3b |
C== 1 a (L== 1 nebo R== 0 nebo PF == 1) |
32 |
add r11,sp,#xx |
FC |
4 |
R== 1 a Reg ! = 7 |
32 |
vpush {d8-dE} |
E0 E7 |
5 |
Stack Adjust! = 0 a PF== 0 |
16/32 |
sub sp,sp,#xx |
00-7F/E8-EB |
Je vždy k dispozici pokyn 1-li H bit nastaven na hodnotu 1.
Nastavit řetězení rámec, pokyn 3a nebo 3b je k dispozici-li C je nastaven bit.Je 16 bitů mov Pokud žádné jiné registry než r11 a LR odesílají; v ostatních případech je 32-bit add.
Pokud je zadán úprav se-přeložen, pokyn 5 je úprava explicitní zásobníku.
Pokyny 2 a 4 jsou nastaveny v závislosti na tom, zda je třeba zadat push.Tato tabulka shrnuje, které registry jsou uloženy na základě C, L, R, a PF polí.Ve všech případech N rovná Reg + 4, E rovná Reg + 8, a S je rovno (~Stack Adjust) & 3.
C |
L |
R |
PF |
Celočíselných registrech posunuta |
Zaregistruje VFP posunuta |
---|---|---|---|---|---|
0 |
0 |
0 |
0 |
R4-rN |
žádná |
0 |
0 |
0 |
1 |
rS-rN |
žádná |
0 |
0 |
1 |
0 |
žádná |
D8 dE |
0 |
0 |
1 |
1 |
rS-r3 |
D8 dE |
0 |
1 |
0 |
0 |
R4-rN, LR |
žádná |
0 |
1 |
0 |
1 |
rS-rN, LR |
žádná |
0 |
1 |
1 |
0 |
LR |
D8 dE |
0 |
1 |
1 |
1 |
rS-r3, LR |
D8 dE |
1 |
0 |
0 |
0 |
R4-rN, r11 |
žádná |
1 |
0 |
0 |
1 |
rS-rN, r11 |
žádná |
1 |
0 |
1 |
0 |
R11 |
D8 dE |
1 |
0 |
1 |
1 |
rS-r3, r11 |
D8 dE |
1 |
1 |
0 |
0 |
R4-rN, r11 LR |
žádná |
1 |
1 |
0 |
1 |
rS- rN, r11 LR |
žádná |
1 |
1 |
1 |
0 |
R11 LR |
D8 dE |
1 |
1 |
1 |
1 |
rS-r3, r11, LR |
D8 dE |
Epilogů pro zpracování kanonické funkce podobně jako formulář, ale pozpátku a některé další možnosti.Epilogu mohou být dlouhé až pro 5 pokyny a jeho formulář je dáno striktně formě prologu.
Instrukce |
OpCode předpokládá přítomen, je-li: |
Velikost |
OpCode |
---|---|---|---|
6 |
Stack Adjust! = 0 a EF== 0 |
16/32 |
add sp,sp,#xx |
7 |
R== 1 a Reg ! = 7 |
32 |
vpop {d8-dE} |
8 |
C==1 or (L==1 and H==0) or R==0 or EF==1 |
16/32 |
pop {registers} |
9a |
H== 1 a L== 0 |
16 |
add sp,sp,#0x10 |
9b |
H== 1 a L== 1 |
32 |
ldr pc,[sp],#0x14 |
10a |
Ret==1 |
16 |
bx reg |
10b |
Ret==2 |
32 |
b address |
Instrukce 6 je úprava explicitní zásobníku, pokud je zadáno úprav se-přeložen.Protože PF je nezávislá EF, je možné mít pokyn 5 přítomen bez pokyn 6 nebo naopak.
Pokyny 7 a 8 pomocí stejné logiky jako prologu určete, které registry budou obnoveny ze zásobníku, ale s těmito dvěma změní: první, EF se používá v místě vlastnosti PF; druhý, pokud Ret = 0, pak LR je nahrazen PC v seznamu registru a epilogu ukončí okamžitě.
Pokud H je nastavena, pak pokyn 9a nebo 9b je k dispozici.9a instrukcí se používá při L je 0, chcete-li označit, že LR není v zásobníku.V takovém případě je ručně upravená zásobníku a Ret musí být 1 nebo 2. Chcete-li určit explicitní return.9b instrukcí se používá při L je 1, označuje konec early epilogu a můžete vrátit a upravit zásobníku současně.
Pokud epilogu nebyla již ukončeno, pak buď pokyn 10a nebo 10b je k dispozici, označíte 16bitové nebo 32bitové větvení, na základě hodnoty z Ret.
.xdata záznamů
Když formát sbalené unwind je nedostatečné k popisu prohlášení funkce, je nutné vytvořit záznam .xdata proměnné délky.Adresa tohoto záznamu je uložena v druhý slovo .pdata záznamu.Formát .xdata je sbalené proměnné délky sadu slov, která má čtyři části:
1 nebo 2 slovo hlavičku, která popisuje celkovou velikost strukturu .xdata a poskytuje funkce klíče data.Druhý slovo je k dispozici pouze, pokud Epilogue Count a Code Words obě pole jsou nastavena na hodnotu 0.Pole jsou rozdělen v této tabulce:
Word
Bity
Účel
0
0-17
Function Lengthje 18-bit pole, které udává celkovou délku funkce v bajtech dělené 2.Je-li funkci je větší než 512 KB, musí více záznamů .pdata a .xdata použít k popisu funkce.Další informace naleznete v části velké funkce v tomto dokumentu.
0
18-19
Versje pole 2-bit, který popisuje verzi zbývající xdata.Aktuálně je definována pouze verze 0; hodnoty 1-3, jsou vyhrazena.
0
20
Xje 1-bit pole, které označuje přítomnost (1) nebo nepřítomnost (0) data výjimky.
0
21
Eje 1-bit pole, která určuje, že je informace, které popisují jedné epilogu balí do hlavičky (1) a že vyžaduje, aby později další obor slova (0).
0
22
Fje 1-bit pole, které označuje, že tento záznam popisuje funkce fragment (1) nebo úplná funkce (0).Fragment znamená, že neexistuje žádná prologu a zda mají být ignorovány všechny prologu zpracování.
0
23-27
Epilogue Countje 5-bit pole, která má dvě význam, v závislosti na stavu E bit:
Pokud E je 0, toto pole je počet z celkového počtu výjimek obory popsané v oddílu 3.Pokud existuje více než 31 oborů ve funkci, pak toto pole a hodnota parametru Code Words pole musí oba být nastaveno na hodnotu 0 označuje, že word rozšíření je vyžadována.
Pokud E je 1, toto pole určuje index první unwind kód, který popisuje pouze epilogu.
0
28-31
Code Words4-bit pole, které určuje počet slov 32bitový musí obsahovat všechny kódy unwind v části 4.Je-li více než 15 slova jsou požadovány pro více než 63 unwind kód bajtů, toto pole a hodnota parametru Epilogue Count pole musí oba být nastaveno na hodnotu 0 označuje, že word rozšíření je vyžadována.
1
0-15
Extended Epilogue Countje 16bitové pole, které poskytuje více místa pro kódování neobvykle velký počet epilogů.Rozšíření slovo, které obsahuje toto pole je k dispozici pouze, pokud Epilogue Count a Code Words pole v první slovo záhlaví jsou oba nastavena na hodnotu 0.
1
16-23
Extended Code Wordsje 8-bit pole, které poskytuje více místa pro kódování neobvykle velký počet unwind kód slova.Rozšíření slovo, které obsahuje toto pole je k dispozici pouze, pokud Epilogue Count a Code Words pole v první slovo záhlaví jsou oba nastavena na hodnotu 0.
1
24-31
Vyhrazena
Po data výjimky – Pokud E bit v hlavičce byl nastaven na hodnotu 0 – seznam obsahuje informace o oborech epilogu, které jsou zabaleny ho, abyste slovo a uložen v pořadí podle zvýšení počáteční posun.Každý obor obsahuje tato pole:
Bity
Účel
0-17
Epilogue Start Offsetpole 18-bit popisující posun epilogu, v bajtech dělené 2 vzhledem ke spuštění funkce je.
18-19
Respole 2-bit je vyhrazen pro budoucí rozšíření.Jeho hodnota musí být 0.
20-23
Conditionje 4-bit pole, které poskytuje podmínku, pod kterým je spouštěn epilogu.Nepodmíněné epilogů by měl být nastaven na 0xE, které označuje "vždy".(Epilogu musí být zcela podmíněné nebo zcela nepodmíněné a v režimu jezdce-2 epilogu začíná první instrukce následující po IT opcode.)
24-31
Epilogue Start Indexpole 8-bit určující bajtu index první unwind kód, který popisuje tuto epilogu je.
Po vstupu do seznamu oborů epilogu pole bajtů, které obsahují unwind kódy, které jsou podrobně popsány v sekci odvíjejí kódy v tomto článku.Toto pole je uvedena na konci na nejbližší hranici celého slova.Bajty jsou uloženy v malé endian pořadí tak, že mohou být přímo načteny v malé endian režimu.
Pokud X pole v hlavičce je 1, bajtů kódu unwind následuje obslužná rutina informace o výjimce.To se skládá z jednoho Exception Handler RVA obsahující adresu obslužná rutina výjimky, následují (proměnné délky) množství dat, které jsou vyžadovány týmem obslužná rutina výjimky.
Záznam .xdata je navržen tak, aby bylo možné načíst první 8 bajtů a vypočítat na plnou velikost záznamu není včetně délka data proměnné velikosti výjimky, která následuje.Tento fragment kódu vypočte velikost položky:
ULONG ComputeXdataSize(PULONG *Xdata)
{
ULONG EpilogueScopes;
ULONG Size;
ULONG UnwindWords;
if ((Xdata[0] >> 23) != 0) {
Size = 4;
EpilogueScopes = (Xdata[0] >> 23) & 0x1f;
UnwindWords = (Xdata[0] >> 28) & 0x0f;
} else {
Size = 8;
EpilogueScopes = Xdata[1] & 0xffff;
UnwindWords = (Xdata[1] >> 16) & 0xff;
}
if (!(Xdata[0] & (1 << 21))) {
Size += 4 * EpilogueScopes;
}
Size += 4 * UnwindWords;
if (Xdata[0] & (1 << 20)) {
Size += 4;
}
return Size;
}
Athough prologu a každý epilogu má index do unwind kódy, je mezi nimi sdílet v tabulce.Není například neobvyklé, že tito uživatelé mohou všechny sdílet stejnou unwind kódy.Doporučujeme, aby kompilátor autory optimalizovat pro tento případ, protože největší index, který lze zadat, je 255 a celkový počet unwind kódy možný pro určité funkce, která omezuje.
Odvíjejí kódy
Pole unwind kódy je fond sekvence instrukcí, které popisují, přesně jak zrušení efektů prologu v pořadí, ve kterém musí být operace vrátit zpět.Unwind kódy představují sadu minimálním pokyn, zašifrované jako řetězec bajtů.Po dokončení provádění zpáteční adresa pro volání funkce je v registru LR a všechny nezávislé registry budou obnoveny na jejich hodnoty v době, kdy byla zavolána funkce.
Pokud výjimek byly zaručena pouze někdy dochází v těle funkce a nikdy v rámci prologu nebo epilogu, pak pouze jeden odvíjejí by sekvence nezbytné.Však unwinding modelu systému Windows vyžaduje schopnost odvíjejí v rámci částečně provedeno prologu nebo epilogu.Chcete-li přizpůsobit tento požadavek, byly unwind kódy pečlivě navrženy mít jednoznačné mapování 1: 1 pro každý relevantní opcode v prologu a epilogu.Tato akce nemá vliv na několik:
Je možné vypočítat délka prologu a epilogu určovat počet unwind kódy.To lze provést i s pokyny proměnné délky jezdce-2, protože existují různé mapování pro 16bitové a 32bitové operační kódy.
Podle počtu pokynů před začátek oboru epilogu, je možné přeskočit ekvivalentní počet unwind kódy a provedení zbytek posloupnost k dokončení částečně provést odvíjejí, aby fungoval epilogu.
Podle počtu pokynů do konce roku prologu, je možné přeskočit ekvivalentní počet unwind kódy a spustit zbytek sekvenci vrátit pouze ty části prologu, které dokončení provádění.
V následující tabulce jsou uvedeny mapování z unwind kódy pro operační kódy.Nejběžnější kódy jsou jen jeden bajtů, zatímco méně běžně stojí vyžadují dva, tři nebo dokonce čtyři bajtů.Každý kód je uložen z nejvýznamnější bajtové nejméně významné bajty.Strukturu unwind kódu se liší od kódování, popsané v ARM EABI, protože tyto unwind kódy určené k mapování 1: 1 na opkódy v prologu a epilogu tak, aby povoloval prohlášení částečně provést prologů a epilogů.
Bajty 1 |
Bajty 2 |
Bajty 3 |
Bajty 4 |
Opsize |
Vysvětlení |
---|---|---|---|---|---|
00 7F |
16 |
add sp,sp,#X kde X je (kód & 0x7F) * 4 |
|||
80 BF |
00-FF |
32 |
pop {r0-r12, lr} kde je LR odebrány, pokud kód & 0x2000 a r r0-12 jsou odebrány, pokud odpovídající bit je nastavena v 0x1FFF & kódu |
||
C0 CR |
16 |
mov sp,rX kde X je 0x0F & kódu |
|||
D0 D7 |
16 |
pop {r4-rX,lr} kde X je (kód & 0x03) + 4 a LR odebrány, pokud kód & 0x04 |
|||
D8 SV |
32 |
pop {r4-rX,lr} where X is (Code & 0x03) + 8 and LR is popped if Code & 0x04 |
|||
E0 E7 |
32 |
vpop {d8-dX} kde X je (kód & 0x07) + 8 |
|||
E8 EB |
00-FF |
32 |
addw sp,sp,#X kde X je (kód & 0x03FF) * 4 |
||
ES ED |
00-FF |
16 |
pop {r0-r7,lr} kde je LR odebrány, pokud kód & 0x0100 a r0 – r7 jsou odebrány, pokud odpovídající bit je nastavena v 0x00FF & kódu |
||
É |
00 0F |
16 |
specifické pro společnost Microsoft |
||
É |
10-FF |
16 |
K dispozici |
||
EF |
00 0F |
32 |
ldr lr,[sp],#X kde X je (kód & 0x000F) * 4 |
||
EF |
10-FF |
32 |
K dispozici |
||
F0 F4 |
- |
K dispozici |
|||
F5 |
00-FF |
32 |
vpop {dS-dE} kde S je (kód & 0x00F0) >> je 4 a E & 0x000F kódu |
||
F6 |
00-FF |
32 |
vpop {dS-dE} kde S je ((Code & 0x00F0) >> 4) + 16 a E je (kód & 0x000F) + 16 |
||
F7 |
00-FF |
00-FF |
16 |
add sp,sp,#X kde X je (kód & 0x00FFFF) * 4 |
|
F8 |
00-FF |
00-FF |
00-FF |
16 |
add sp,sp,#X kde X je (kód & 0x00FFFFFF) * 4 |
F9 |
00-FF |
00-FF |
32 |
add sp,sp,#X kde X je (kód & 0x00FFFF) * 4 |
|
DM |
00-FF |
00-FF |
00-FF |
32 |
add sp,sp,#X kde X je (kód & 0x00FFFFFF) * 4 |
FB |
16 |
Nop (16 bitů) |
|||
FC |
32 |
Nop (32 bitů) |
|||
PROCESU TYPU DÉMON FILTRU |
16 |
end + 16bitové nop v epilogu |
|||
I |
32 |
end + 32-bit nop in epilogue |
|||
FF |
- |
end |
Zobrazuje rozsah hexadecimálních hodnot pro každý byte v rámci směrového unwind Code, spolu s velikost opcode Opsize a odpovídající původní interpretaci instrukcí.U prázdných buněk naznačují kratší unwind kódy.V pokynech, které mají vysoké hodnoty pokrývá více bajtů jsou uloženy nejprve nejvýznamnější bitů.Opsize Pole zobrazuje velikost implicitní opcode spojené s každou operaci jezdce-2.Zřejmé duplicitní položky v tabulce s různá kódování se používají k rozlišení opcode různé velikosti.
Unwind kódy jsou navrženy tak, aby prvního bajtu kódu říká celková velikost v bajtech kódu a velikost odpovídající opcode v datovém proudu instrukcí.K výpočtu velikosti prologu nebo epilogu, procházet unwind kódy od začátku sekvenci na konec a pomohou zjistit, jak dlouho je odpovídající opcode vyhledávací tabulku nebo podobné metody.
Odvíjejí kódy 0xFD a Bugcheck 0xFE jsou ekvivalentní kód regulární konce 0xFF, ale účet pro jeden opcode navíc nop v případě epilogu 16bitové nebo 32bitové verze.Pro prologů jsou právě ekvivalentní kódů 0xFD, Bugcheck 0xFE a 0xFF.This accounts for the common epilogue endings bx lr or b <tailcall-target>, which don’t have an equivalent prologue instruction.Toto se zvýší, šance, že se odvíjejí sekvence může být sdílena mezi prologu a epilogů.
V řadě případů musí být možné použít stejnou sadu unwind kódy pro prologu a všechny epilogů.Nicméně pro zpracování prohlášení částečně provedeno prologů a epilogů, bude pravděpodobně nutné mít více sekvence unwind kódu, které se liší v pořadí nebo chování.Z tohoto důvodu každého epilogu má vlastní index do pole unwind, chcete-li zobrazit kde začít provádění.
Unwinding částečné prologů a epilogů
Nejběžnější unwinding případem je, když dojde výjimce v těle funkce mimo prologu a všechny epilogů.V takovém případě unwinder provede kódy na začátku unwind pole s indexem nula a pokračuje, dokud nedojde ukončení opcode jejího výskytu není nalezeno.
Pokud dojde k výjimce při prologu ani epilogu je prováděna, zásobníku je vytvořen pouze částečně a unwinder musíte určit přesně co bylo provedeno za účelem správně vrátit zpět.
Zvažte například tuto prologu a epilogu sekvenci:
0000: push {r0-r3} ; 0x04
0002: push {r4-r9, lr} ; 0xdd
0006: mov r7, sp ; 0xc7
...
0140: mov sp, r7 ; 0xc7
0142: pop {r4-r9, lr} ; 0xdd
0146: add sp, sp, #16 ; 0x04
0148: bx lr
Vedle každé opcode je vhodné unwind kód k popisu této operace.Posloupnost unwind kódy pro prologu je obrázek zrcadlení unwind kódy pro epilogu, není počítání finální instrukcí.Tento případ je běžné a je důvod, proč unwind kódy pro prologu jsou vždy předpokládá, že má být uložen v obráceném pořadí z pořadí zpracování prologu.Díky tomu nám společnou sadu unwind kódy:
0xc7, 0xdd, 0x04, 0xfd
Kód 0xFD je speciální kód na konci sekvenci, která znamená, že je epilogu jedné instrukce 16bitové delší než prologu.Díky větší sdílení unwind kódy.
V příkladu Pokud dojde k výjimce, zatímco je prováděna tělo funkce mezi prologu a epilogu, unwinding začíná epilogu věc, na posunu 0 epilogu kódu.Odpovídá posunu 0x140 v příkladu.Unwinder provede úplné unwind sekvenci vzhledem k tomu, že nebyl proveden žádný vyčištění.Dojde-li místo toho výjimka jedné instrukce po začátku epilogu kódu, můžete unwinder úspěšně odvíjejí přeskočením první unwind kód.Zadané mapování 1: 1 mezi operační kódy a odvíjejí kódy, je-li unwind z pokyn n v epilogu, přeskočte unwinder první n odvíjejí kódy.
Podobné logiku funguje obráceným pro prologu.Pokud unwind z posunu 0 v prologu, nic nemá pro spuštění.Pokud unwind z jedné instrukce v, sekvenci unwind by měl spustit jeden unwind kód z konce, protože prologu unwind kódy jsou uloženy v obráceném pořadí.V případě Obecné, je-li unwind z pokyn n v prologu, unwind by měl spustí provádění na adrese n odvíjejí kódy z konce seznam kódů.
Prologu a epilogu unwind kódy vždy neodpovídají přesně.V takovém případě unwind kódu pravděpodobně obsahuje několik sekvence kódy.Chcete-li určit posun k zahájení zpracování kódy, použijte tuto logiku:
Pokud unwind z v těle funkce, zahájí unwind kódy v indexu 0 a pokračovat, dokud není dosaženo element end opcode.
Pokud unwind z v rámci epilogu, použijte počáteční index epilogu specifické poskytované epilogu oboru.Vypočítejte, kolik bajtů počítače je od začátku epilogu.Přeskočte vpřed prostřednictvím unwind kódy, dokud všechny pokynů, které jsou již provedena představoval.Spusťte unwind pořadí spouštění v tomto bodě.
Pokud unwind z v rámci prologu, spusťte z indexu 0 v unwind kódy.Výpočet délka kódu prologu z řady a potom vypočítat, kolik bajtů počítače je z konce prologu.Přeskočit vpřed prostřednictvím unwind kódy, dokud všechny odvolat pokynů, které jsou představoval.Spusťte unwind pořadí spouštění v tomto bodě.
Unwind kódy pro prologu musí být vždy první v poli.Jsou také kódy používané pro odvíjejí v případě obecné unwind z v rámci datové části.Žádnou sekvenci kódu pro konkrétní epilogu se měli řídit ihned po sekvenci kódu prologu.
Funkce fragmentů
Pro optimalizaci kódu může být užitečné rozdělit funkce na nesousedících části.Je-li to lze provést, každý fragment funkce vyžaduje svou vlastní samostatné .pdata – a případně .xdata – záznam.
Za předpokladu, že funkce prologu je na začátku funkce a nelze rozdělit, existují čtyři funkce fragment případech:
Prologu pouze; všechny epilogů v jiných fragmenty.
Prologu a jeden nebo více epilogů; Další epilogů v jiných fragmenty.
Žádné prologu nebo epilogů; prologu a jeden nebo více epilogů v jiných fragmenty.
Epilogů pouze; prologu a případně další epilogů v jiných fragmenty.
V prvním případě musí být popsány pouze prologu.To lze provést ve formě compact .pdata obvykle popisující prologu a určením Ret hodnotu 3, která určuje žádné epilogu.Ve formuláři úplná .xdata to lze provést jako obvykle poskytnutí unwind kódy prologu v indexu 0 a zadáním epilogu počtem 0.
Druhém případě je stejně jako normální funkce.Pokud je pouze jeden epilogu ve fragmentu a je na konci fragment, lze použít compact .pdata záznamu.Jinak je nutné použít plnou .xdata záznamu.Mějte na paměti, že jsou posuny zadaný pro začátek epilogu relativní vůči začátek fragmentu není původní spuštění funkce.
Třetí a čtvrtá případů variant první a druhý případů, jsou v uvedeném pořadí, s výjimkou neobsahují prologu.V těchto případech předpokládá se, že existuje kódu před zahájením epilogu a bude považován za část těla funkce, která by obvykle odděleny zrušením účinky prologu.Těchto případech proto musí být kódován pseudo prologu, který popisuje, jak odvíjejí z v rámci datové části, ale které je považován za 0-length při určování, zda se má provést částečné odvíjejí na začátku fragment.Alternativně mohou být tento pseudo prologu označena pomocí stejného unwind kódy jako epilogu, protože jsou pravděpodobně z důvodu operacích ekvivalentní.
V případech třetí a čtvrtý je zadán přítomnost pseudo prologu buď nastavením Flag pole záznamu compact .pdata na 2 nebo nastavením F příznak v hlavičce .xdata na hodnotu 1.V obou případech je zaškrtnutí pro částečné prologu unwind je ignorována, a všechny jiné epilogu unwinds jsou považovány za plnou.
Velké funkce
Fragmenty lze použít k popisu funkcí, které jsou větší než 512 KB omezení vynucená pro bit pole v hlavičce .xdata.K popisu velmi velké funkce, stačí ho rozdělte na fragmenty menší než 512 KB.Každý fragment je třeba upravit tak, aby nerozděluje epilogu do na více místech.
Obsahuje pouze první fragment funkce prologu; všechny ostatní fragmenty jsou označeny jako s žádné prologu.V závislosti na počtu epilogů každý fragment může obsahovat žádný nebo více epilogů.Uvědomte si, že každý obor epilogu v fragment určuje její počáteční posun vzhledem ke spuštění fragment, nikoliv začátek funkce.
Má-li fragment žádné prologu a žádné epilogu, stále vyžaduje svou vlastní .pdata – a případně .xdata – záznam, který chcete popisují, jak odvíjejí v těle funkce.
Zmenšující obalení
Složitější zvláštním případem funkce fragmentů, ve kterých je zmenšující obalení, technika odložit zaregistrujte se uloží od začátku funkce, která má později ve funkci pro optimalizaci pro jednoduché případy, které nevyžadují uložení registru.To lze popsat jako vnější oblast, která přiděluje místo v zásobníku, ale uloží minimální sada registrů a vnitřní oblasti, která ukládá a obnovuje další registrů.
ShrinkWrappedFunction
push {r4, lr} ; A: save minimal non-volatiles
sub sp, sp, #0x100 ; A: allocate all stack space up front
... ; A:
add r0, sp, #0xE4 ; A: prepare to do the inner save
stm r0, {r5-r11} ; A: save remaining non-volatiles
... ; B:
add r0, sp, #0xE4 ; B: prepare to do the inner restore
ldm r0, {r5-r11} ; B: restore remaining non-volatiles
... ; C:
pop {r4, pc} ; C:
Pečlivě zabaleny funkce se obvykle očekává předem přidělit prostor pro doplňující registru uloží v pravidelných prologu a poté provedete uložení registrů pomocí str nebo stm namísto push.Tím zůstane všechny manipulaci s ukazatel na zásobník v původní prologu funkce.
Funkce pečlivě zabaleny příklad musí rozdělit na tři oblasti, které jsou označeny jako A, B a C v komentářích.První oblast pokrývá počáteční funkce až do konce další uloží stálé.Vytvořit záznam .pdata nebo .xdata musí být vytvořena popisující tento fragment jako s prologu a žádné epilogů.
Oblast doprostřed B získá svou vlastní .pdata nebo .xdata záznam, který popisuje fragment, který nemá žádné prologu a žádné epilogu.Však unwind kódy pro tuto oblast musí být stále přítomen vzhledem k tomu, že byl považován za tělo funkce.Kódy musí popisují složený prologu, představující obě původní registry uložené v oblasti A prologu a další registry uloženy před zadáním oblast B, jakoby byly vytvářený jednu posloupnost operací.
Rejstřík uloží pro oblast, kterou B nemůže být považován "vnitřní prologu", protože složený prologu popsané oblasti B musí popisovat prologu A oblast a další registry uložen.Pokud byly fragment B popsané jako s prologu, unwind kódy by vyvolalo také velikost tohoto prologu a neexistuje žádný způsob, jak popisují složený prologu způsobem, který mapuje s operační kódy, které pouze uložit další Registry 1: 1.
Vzhledem k tomu, dokud nebudou dokončena, složené prologu přesně není popsán stav zásobníku musí být uložení další registrů považovány za součást oblast A.
Poslední oblasti C získá svůj vlastní .pdata nebo .xdata záznam popisující fragment, který nemá žádné prologu, ale nemá epilogu.
Je-li práci se zásobníkem provést před zadáním oblast B lze snížit do jedné instrukce, můžete také pracovat alternativní přístup:
ShrinkWrappedFunction
push {r4, lr} ; A: save minimal non-volatile registers
sub sp, sp, #0xE0 ; A: allocate minimal stack space up front
... ; A:
push {r4-r9} ; A: save remaining non-volatiles
... ; B:
pop {r4-r9} ; B: restore remaining non-volatiles
... ; C:
pop {r4, pc} ; C: restore non-volatile registers
Klíč zde je, že na každou pokyn ohraničení, je plně v souladu s unwind kódy pro oblast zásobníku.Dojde-li unwind před vnitřní push v tomto příkladu, bude považován za součást oblast A a pouze pro oblast prologu je oddělen.Dojde-li unwind po vnitřní push, bude považován za součást oblast B, která nemá žádné prologu, ale má unwind kódy, které popisují vnitřní push a původní prologu z oblasti A.Podobné logiku platí pro vnitřní pop.
Kódování optimalizace
Z důvodu bohatou unwind kódy a schopnost využívání kompaktní a rozšířenou formy dat existuje mnoho možností optimalizace kódování, které má dalšího omezení místa.S účinnou použití těchto technik může být zcela minimální net režií s popisem funkcí a fragmenty pomocí unwind kódy.
Nejdůležitější optimalizace je dejte pozor, abyste zaměňovat prologu/epilogu hranice pro unwinding účely s logické prologu/epilogu hranice z hlediska kompilátoru.Unwinding hranice můžete zmenšit a provedené těsnější zlepšit efektivitu.Můžete například prologu může obsahovat kód, poté, co ověří nastavení zásobníku a provést další ověření.Ale po dokončení všech manipulaci s zásobníku není nutné ke kódování další operace a nic kromě toho lze odebrat z unwinding prologu.
Toto pravidlo stejné platí pro funkci délka.Pokud neexistují data – například literálu fond – epilogu ve funkci, který následuje, neměla by být zahrnuty jako součást funkce délky.Zmenšením funkce kódu, který je součástí funkce jsou mnohem vyšší, aby epilogu budou na velmi konce a kompaktní pravděpodobnosti.záznam pdata lze použít.
V prologu Jakmile se ukazatel na zásobník je uloženo do jiného registru není obvykle nutné k zaznamenání žádné další operační kódy.Odvíjejí funkce, je první věc, která se má provést SP k odstranění uloženého registru a tak další operace nemají žádný vliv na unwind.
Jedním pokyn epilogů nemusejí být zakódován vůbec, buď jako obory nebo jako odvíjejí kódy.Pokud unwind se uskuteční touto instrukcí se před provedením, pak lze předpokládat, chcete-li být z v těle funkce a právě provádění unwind kódy prologu je dostačující.Pokud unwind se provádí po provedení jediné instrukce, pak podle definice bude provedeno v jiné oblasti.
Více instrukcí epilogů nemají ke kódování první instrukcí epilogu, ze stejného důvodu jako předchozí bod: Pokud unwind uskuteční před spuštěním tohoto pokyn, úplná prologu unwind je dostačující.Probíhá-li unwind po pokyn, pak musí být považovány za pouze následující operace.
Odvíjejí kód znovu použít by měla být účinnou.Index založený na určené každého epilogu oboru body na libovolný počáteční bod v poli unwind kódy.Nemá tak, aby odkazoval na začátek předchozí sekvence; může odkazovat uprostřed.Zde je nejlepším postupem je generování sekvenci požadovaný kód a potom scan shodu přesné bajtu ve fondu již kódováním sekvencí a použití jakékoli ideální doplněk jako výchozí bod pro opakované použití.
Pokud po jedním pokyn epilogů jsou ignorovány, nejsou žádné zbývající epilogů, zvažte použití compact .pdata formuláře; stává mnohem vyšší pravděpodobnost neexistují epilogu.
Příklady
V těchto příkladech je základní bitovou kopii na 0x00400000.
Příklad 1: Funkce listu, žádné Locals
Prologue:
004535F8: B430 push {r4-r5}
Epilogue:
00453656: BC30 pop {r4-r5}
00453658: 4770 bx lr
.pdata (pevná, 2 slov):
Word 0
- Function Start RVA= 0x000535F8 (= 0x004535F8 – 0x00400000)
Word 1
Flag= 1, určující kanonické prologu a epilogu formáty
Function Length= 0x31 (= 0x62/2)
Ret= Vrátí 1, určující 16bitové větvení.
H= 0, určující parametry nebyly adresami
R= 0 a Reg = 1, určující push r4 r5 pop
L= 0, určující žádné LR uložit nebo obnovit
C= 0, určující žádné rámce řetězení
Stack Adjust= 0, určující bez úpravy zásobníku
Příklad 2: Vnořené funkce s místní přidělení
Prologue:
004533AC: B5F0 push {r4-r7, lr}
004533AE: B083 sub sp, sp, #0xC
Epilogue:
00453412: B003 add sp, sp, #0xC
00453414: BDF0 pop {r4-r7, pc}
.pdata (pevná, 2 slov):
Word 0
- Function Start RVA= 0x000533AC (= 0x004533AC – 0x00400000)
Word 1
Flag= 1, určující kanonické prologu a epilogu formáty
Function Length= 0x35 (= 0x6A/2)
Ret= 0, určující pop {pc} návratový
H= 0, určující parametry nebyly adresami
R= 0 a Reg = 3, určující push r4 r7 pop
L= 1, určující LR byla uložena/obnovit
C= 0, určující žádné rámce řetězení
Stack Adjust= 3 (= 0x0C/4)
Příklad 3: Vnořené funkce Variadic
Prologue:
00453988: B40F push {r0-r3}
0045398A: B570 push {r4-r6, lr}
Epilogue:
004539D4: E8BD 4070 pop {r4-r6}
004539D8: F85D FB14 ldr pc, [sp], #0x14
.pdata (pevná, 2 slov):
Word 0
- Function Start RVA= 0x00053988 (= 0x00453988 – 0x00400000)
Word 1
Flag= 1, určující kanonické prologu a epilogu formáty
Function Length= 0x2A (= 0x54/2)
Ret= 0, určující pop {pc}-style return (v takovém případě počítači ldr [sp], #0x14 vrátit zpět)
H= byly adresami 1, která určuje parametry
R= 0 a Reg = 2, určující push r4 r6 pop
L= 1, určující LR byla uložena/obnovit
C= 0, určující žádné rámce řetězení
Stack Adjust= 0, určující bez úpravy zásobníku
Příklad 4: Funkce s více epilogů
Prologue:
004592F4: E92D 47F0 stmdb sp!, {r4-r10, lr}
004592F8: B086 sub sp, sp, #0x18
Epilogues:
00459316: B006 add sp, sp, #0x18
00459318: E8BD 87F0 ldm sp!, {r4-r10, pc}
...
0045943E: B006 add sp, sp, #0x18
00459440: E8BD 87F0 ldm sp!, {r4-r10, pc}
...
004595D4: B006 add sp, sp, #0x18
004595D6: E8BD 87F0 ldm sp!, {r4-r10, pc}
...
00459606: B006 add sp, sp, #0x18
00459608: E8BD 87F0 ldm sp!, {r4-r10, pc}
...
00459636: F028 FF0F bl KeBugCheckEx ; end of function
.pdata (pevná, 2 slov):
Word 0
- Function Start RVA= 0x000592F4 (= 0x004592F4 – 0x00400000)
Word 1
Flag= 0, určující .xdata záznam přítomen (požadováno z důvodu více epilogů)
.xdata address-0x00400000
.xdata (proměnné, 6 slova):
Word 0
Function Length= 0x0001A3 (= 0x000346/2)
Vers= 0, označující první verzi xdata
X= 0, určující žádná data výjimky
E= 0, určující seznam epilogu oborů
F= 0, určující funkce úplný popis, včetně prologu
Epilogue Count= 0x04, určující 4 obory celkový epilogu
Code Words= 0x01, určující jedno slovo 32bitový unwind kódů
Slova popisující 4 obory epilogu na 4 umístění 1 – 4.Každý obor má společnou sadu unwind kódy, sdílet s prologu posunem 0x00 a nepodmíněné, určíte podmínku 0x0E (vždy).
Odvíjejí kódy, počínaje Word 5: (sdílena mezi prologu/epilogu)
Odvíjejí kódu 0 = 0x06: sp + (6 << 2)
Odvíjejí kódu 1 = 0xDE: pop {r4 r10, lr}
Odvíjejí kód 2 = 0xFF: konec
Příklad 5: Funkce se dynamické zásobníku a vnitřní epilogu
Prologue:
00485A20: B40F push {r0-r3}
00485A22: E92D 41F0 stmdb sp!, {r4-r8, lr}
00485A26: 466E mov r6, sp
00485A28: 0934 lsrs r4, r6, #4
00485A2A: 0124 lsls r4, r4, #4
00485A2C: 46A5 mov sp, r4
00485A2E: F2AD 2D90 subw sp, sp, #0x290
Epilogue:
00485BAC: 46B5 mov sp, r6
00485BAE: E8BD 41F0 ldm sp!, {r4-r8, lr}
00485BB2: B004 add sp, sp, #0x10
00485BB4: 4770 bx lr
...
00485E2A: F7FF BE7D b #0x485B28 ; end of function
.pdata (pevná, 2 slov):
Word 0
- Function Start RVA= 0x00085A20 (= 0x00485A20 – 0x00400000)
Word 1
Flag= 0, určující .xdata záznam přítomen (je třeba z důvodu více epilogů)
.xdata address-0x00400000
.xdata (proměnné, 3 slova):
Word 0
Function Length= 0x0001A3 (= 0x000346/2)
Vers= 0, označující první verzi xdata
X= 0, určující žádná data výjimky
E= 0, určující seznam epilogu oborů
F= 0, určující funkce úplný popis, včetně prologu
Epilogue Count= 0x001, určující celkový epilogu obor 1
Code Words= 0x01, určující jedno slovo 32bitový unwind kódů
Slovo 1: Epilogu oboru na posunu 0xC6 (= 0x18C/2), spuštění unwind kód index 0x00 a s podmínkou 0x0E (vždy)
Odvíjejí kódy, počínaje Word 2: (sdílena mezi prologu/epilogu)
Odvíjejí kódu 0 = 0xC6: sp = r6
Odvíjejí kódu 1 = 0xDC: pop {r4 r8, lr}
Odvíjejí kód 2 = 0x04: sp + (4 << 2)
Odvíjejí kód 3 = 0xFD: konec počty jako 16bitové instrukce pro epilogu
Příklad 6: Funkce se obslužná rutina výjimky
Prologue:
00488C1C: 0059 A7ED dc.w 0x0059A7ED
00488C20: 005A 8ED0 dc.w 0x005A8ED0
FunctionStart:
00488C24: B590 push {r4, r7, lr}
00488C26: B085 sub sp, sp, #0x14
00488C28: 466F mov r7, sp
Epilogue:
00488C6C: 46BD mov sp, r7
00488C6E: B005 add sp, sp, #0x14
00488C70: BD90 pop {r4, r7, pc}
.pdata (pevná, 2 slov):
Word 0
- Function Start RVA= 0x00088C24 (= 0x00488C24 – 0x00400000)
Word 1
Flag= 0, určující .xdata záznam přítomen (je třeba z důvodu více epilogů)
.xdata address-0x00400000
.xdata (proměnné, 5 slova):
Word 0
Function Length= 0x000027 (= 0x00004E/2)
Vers= 0, označující první verzi xdata
X= 1, určující přítomen data výjimky
E= 1, určující jedné epilogu
F= 0, určující funkce úplný popis, včetně prologu
Epilogue Count= 0x00, označující začátek kódy unwind epilogu posunem 0x00
Code Words= 0x02, určující dvě slova 32bitový unwind kódů
Odvíjejí kódy, počínaje Word 1:
Odvíjejí kódu 0 = 0xC7: sp = r7
Odvíjejí kódu 1 = 0x05: sp + (5 << (2).
Odvíjejí kód 2 = 0xed bez možnosti odinstalování/0x90: pop {r4, r7, lr}
Odvíjejí kód 4 = 0xFF: konec
Určuje obslužnou rutinu výjimky, Word 3 = 0x0019A7ED (= 0x0059A7ED – 0x00400000)
Slova 4 a mimo jsou data vložená výjimky
Příklad 7: Funclet
Function:
00488C72: B500 push {lr}
00488C74: B081 sub sp, sp, #4
00488C76: 3F20 subs r7, #0x20
00488C78: F117 0308 adds r3, r7, #8
00488C7C: 1D3A adds r2, r7, #4
00488C7E: 1C39 adds r1, r7, #0
00488C80: F7FF FFAC bl target
00488C84: B001 add sp, sp, #4
00488C86: BD00 pop {pc}
.pdata (pevná, 2 slov):
Word 0
- Function Start RVA= 0x00088C72 (= 0x00488C72 – 0x00400000)
Word 1
Flag= 1, určující kanonické prologu a epilogu formáty
Function Length= 0x0B (= 0x16/2)
Ret= 0, určující pop {pc} návratový
H= 0, určující parametry nebyly adresami
R= 0 a Reg = 7 určující žádné registry nebyly uloženy obnovit
L= 1, určující LR byla uložena/obnovit
C= 0, určující žádné rámce řetězení
Stack Adjust= 1, určující 1 x 4 bajtové zásobníku úpravy
Viz také
Referenční dokumentace
Běžné problémy s migrací ARM v prostředí Visual C++