Udostępnij za pośrednictwem


Prolog i epilog

Każda funkcja, który przydziela miejsce stosu wywołań inne funkcje, zapisuje rejestry nieulotna lub używa obsługi wyjątków musi mieć prologu, w których limity adres zostały opisane w danych odkręcanie skojarzonych z wpisu tabeli odpowiedniej funkcji (zobacz Obsługa wyjątków (x64)).Prologu zapisuje argument rejestry w adresy domowe w razie potrzeby odkłada nieulotna rejestrów na stosie, przydziela stałej części stosu dla mieszkańców i prowizorów, a opcjonalnie określa wskaźnik ramki.Związanych z nimi odkręcanie danych musi zawierać opis akcji prologu i musi dostarczyć informacje niezbędne do cofnąć efekt kodu prologu.

Jeśli alokacja stałych w stosie jest więcej niż jedną stronę (to znaczy większy niż 4096 bajtów), jeśli to możliwe, że Alokacja stosu może obejmować więcej niż jedną stronę pamięci wirtualnej i, w związku z tym, musi być sprawdzona alokacji, zanim faktycznie przydzielone.Specjalnej procedury, to można wywoływać ze prologu i który nie zniszczy żadnego z rejestrów argument jest przewidzianej do tego celu.

Preferowaną metodą zapisywania nieulotna rejestrów jest aby przenieść je na stosie przed przyznaniem środków stosu.Jeśli Alokacja stosu stałe były wykonywane przed nieulotna rejestrów, które zostały zapisane, to najprawdopodobniej o pojemności 32-bitowe mogą być wymagane dla adresu zapisanego zarejestrować obszaru (Podobno wypycha rejestrów są tylko tak szybko, jak ruchy i powinny pozostać tak dającej się przewidzieć przyszłości, pomimo dorozumianych zależność między wypycha).Rejestry nieulotna można zapisywać w dowolnej kolejności.Jednak pierwszego użycia nieulotna rejestru w prologu należy go zapisać.

Kod dla typowych prologu może być:

mov       [RSP + 8], RCX
push   R15
push   R14
push   R13
sub      RSP, fixed-allocation-size
lea      R13, 128[RSP]
...

Ta prologu przechowuje rejestr argumentu RCX w położeniu do domu, zapisuje nieulotnej rejestruje R13 R15, przydziela stałą część ramek stosu i ustanawia wskaźnika klatki, wskazujący 128 bajtów do obszaru alokacji środków.Za pomocą Przesunięcie umożliwia alokacji stałych powierzchni należy się zająć z przesunięciem jeden bajt.

Jeśli rozmiar alokacji środków jest większa niż lub równa jedną stronę pamięci, funkcja pomocnicza musi wywołana przed modyfikacją RSP.Ten pomocnik, __chkstk, jest odpowiedzialny za sondowania z zakresu wobec-być przydzielane do stosu, aby zapewnić, że stosu jest rozszerzany prawidłowo.W takim przypadku w poprzednim przykładzie prologu zamiast tego będzie:

mov       [RSP + 8], RCX
push   R15
push   R14
push   R13
mov      RAX,  fixed-allocation-size
call   __chkstk
sub      RSP, RAX
lea      R13, 128[RSP]
...

Osoba udzielająca pomocy __chkstk nie zmodyfikuje wszelkich rejestrów, inne niż R10, R11 i kodów stanu.W szczególności to zwróci RAX bez zmian i pozostawić wszystko nieulotna rejestrów i rejestry przekazywania argumentu niezmodyfikowany.

Kod Epilog znajduje się przy każdym wejściu do funkcji.Jest zazwyczaj tylko jeden prologu, może istnieć wiele epilogs.Kod Epilog przycina stosem, aby jego rozmiar alokacji środka (Jeśli to konieczne), zwalnia alokacji stosu stałych, przywraca nieulotna rejestrów poprzez wizytę ich zapisane wartości ze stosu i zwraca.

Kod epilog ścisły zbiór zasad dla kodu odkręcanie muszą być zgodne z niezawodnie odkręcania poprzez wyjątki i przerwań.Zmniejsza to ilość odkręcanie wymagane dane, ponieważ brak dodatkowych danych jest niezbędnych do zapisania każdej epilog.Zamiast tego kodu odkręcanie można określić, że epilog jest wykonywany przez skanowania do przodu przez strumień kodu do identyfikacji epilog.

Wskaźnik ramki nie jest używany w funkcji, a następnie epilog musi najpierw zwolnić stałej części stosu zostanie wyrzuconych nieulotna rejestrów, a sterowanie jest zwracane do wywoływania funkcji.Na przykład:

add      RSP, fixed-allocation-size
pop      R13
pop      R14
pop      R15
ret

Jeśli wskaźnik ramki jest używany w funkcji, stosu musi zostać przycięte do swojej alokacji środków przed wykonaniem oznaczania epilog.Jest to technicznie nie jest częścią epilog.Na przykład następujące epilog można cofnąć prologu poprzednio używane:

lea      RSP, -128[R13]
; epilogue proper starts here
add      RSP, fixed-allocation-size
pop      R13
pop      R14
pop      R15
ret

W praktyce gdy używany jest wskaźnika klatki, istnieje bez żadnego powodu, aby dopasować RSP w dwóch etapach, więc zamiast tego zostaną wykorzystane następujące epilog:

lea      RSP, fixed-allocation-size – 128[R13]
pop      R13
pop      R14
pop      R15
ret

Są to tylko prawidłowe formularze dla epilog.Musi się składać z albo add RSP,constant lub lea RSP,constant[FPReg], a następnie szereg zero lub więcej punktów obecności 8-bajtowa rejestru i znak powrotu lub skok.(Tylko podzbiór instrukcji jmp są dozwolone w epilog.Są wyłącznie z klasy jmps z odwołań do pamięci ModRM gdzie pole mod ModRM wartość 00.Korzystanie z jmps w epilog z wartością pola mod ModRM 01 lub 10 jest zabronione.Zobacz Tabela A-15 w programista architekturę x 86-64 procesory AMD podręcznika Volume 3: ogólnego przeznaczenia i instrukcje systemu, więcej informacji o dopuszczalnych odwołań ModRM.).Żaden inny kod może się pojawić.W szczególności nic nie może zostać zaplanowana w epilog, włączając załadunek zwracanej wartości.

Należy zauważyć, że w podczas wskaźnika klatki nie jest używany, należy użyć epilog add RSP,constant zostać dealokowany stałej części stosu.Nie można używać lea RSP,constant[RSP] zamiast.To ograniczenie istnieje, więc kod odkręcanie ma mniejszą liczbę wzorców, które rozpoznają przy wyszukiwaniu epilogs.

Następujących reguł pozwala kod odkręcanie, aby ustalić, że epilog jest aktualnie wykonywane i symulować wykonanie pozostałej części epilog, aby umożliwić odtworzenie kontekście wywoływania funkcji.

Zobacz też

Informacje

Konwencje kodowania x64