Overview of ARM ABI Conventions
Interfejs binarne aplikacji (ABI) dla kodu skompilowanego dla systemu Windows na procesorach ARM opiera się na standardowych EABI ARM.W tym artykule służy do oznaczenia klucza różnic między systemu Windows za pośrednictwem ARM i standard.Aby uzyskać więcej informacji o standardowych EABI ARM, zobacz aplikacji binarne interfejsu (ABI) dla architektury ARM.
Podstawowa wymagania
Systemu Windows w imieniu zakłada, że jest uruchomiona w ramach architektury ARMv7 we wszystkich przypadkach.Zmiennoprzecinkowe pomocy technicznej w postaci VFPv3 D32 lub nowszy musi być obecny w sprzętu.VFP musi obsługiwać zarówno pojedynczej precyzji i podwójnej precyzji zmiennoprzecinkowych sprzętu.Środowisko wykonawcze systemu Windows nie obsługuje emulację zmiennoprzecinkowych, aby umożliwić działający na sprzęcie bez VFP.
Zaawansowane pomocy technicznej SIMD Extensions (NEONU) — obejmuje ona zarówno całkowitą i operacje zmiennoprzecinkowe — musi być również stosowany w sprzętu.Nie obsługę w czasie wykonywania dla emulacji jest udostępniana.
Obsługa dzielenie liczby całkowitej (UDIV/SDIV) zdecydowanie zaleca się, ale nie jest wymagane.Platformy, które nie mają wsparcia dzielenie liczby całkowitej może spowodować zmniejszenie wydajności, ponieważ te operacje muszą być zablokował i prawdopodobnie poprawiono.
Endianness
Wykonuje systemu Windows za pośrednictwem ARM w trybie małoendiański.Zarówno kompilator Visual C++ i środowiska wykonawczego systemu Windows oczekują małoendiański danych we wszystkich przypadkach.Chociaż instrukcja SETEND w instrukcji ARM ustawić architektura (ISA) umożliwia nawet trybu użytkownika kodu w celu zmiany bieżącego endianness, spowoduje to nie jest zalecane, ponieważ jest on niebezpieczne dla aplikacji.Jeśli wyjątek jest generowany w trybie wielkoendiański zachowanie jest nieprzewidywalnego i może prowadzić do błędu aplikacji w trybie użytkownika lub operacji wykrywania błędów w trybie jądra.
Wyrównanie
Chociaż systemu Windows umożliwia sprzętu ARM do obsługi niewyrównane całkowitą przejrzysty, dostęp wyrównanie błędów można wygenerować nadal w niektórych sytuacjach.Wykonaj te zasady wyrównanie:
Średnich wyraz pół (16-bitowe) i ładuje całkowitą o rozmiarze word (32-bitowe) i magazyny nie muszą być wyrównane.Sprzęt obsługuje je wydajne i przezroczysty.
Powinno być wyrównane zmiennoprzecinkowych ładunków i magazynów.Jądro obsługuje odwołań do niewyrównanych obciążenia i przechowuje przezroczysty, ale przy użyciu znaczne obciążenie.
Ładowanie lub przechowywania liczba o podwójnej precyzji (LDRD/STRD) i powinno być wyrównane wielu operacji (LDM/STM).Jądro obsługuje większość z nich przezroczysty, ale przy użyciu znaczne obciążenie.
Pełny dostęp bez buforowania pamięci muszą być dostosowane, nawet w przypadku dostęp do liczby całkowitej.Dostęp do odwołań do niewyrównanych powodować błąd wyrównania.
Zestaw instrukcji
Instrukcja dla systemu Windows w imieniu ogranicza się wyłącznie do 2 przycisku suwaka.Każdy kod wykonany na tej platformie powinien uruchomić i pozostają w trybie przycisku suwaka we wszystkich przypadkach.Podjęto próbę, aby przełączyć się do starszej wersji zestaw instrukcji ARM może się powieść, ale jeśli tak, wszystkie wyjątki lub przerwania, które występują może prowadzić do błędu aplikacji w trybie użytkownika lub operacji wykrywania błędów w trybie jądra.
Efekt po stronie tego wymagania jest wszystkie wskaźniki kod musi bit niska wartość.Jest to, aby po są ładowane i za pomocą BLX lub BX, zgodnie z, procesor będzie nadal pracować w trybie przycisku suwaka i próbuj do wykonywania kodu docelowy jako instrukcje ARM 32-bitowy.
Instrukcje IT
Użyj instrukcji IT w kodzie przycisku suwaka 2 jest niedozwolone, z wyjątkiem tych szczególnych przypadkach:
Instrukcja IT tylko może służyć do zmodyfikować jednej instrukcji docelowego.
Instrukcja docelowym musi być instrukcję 16-bitowe.
Instrukcja docelowy musi mieć jedną z tych:
Używa 16-bitowe
Class
Ograniczenia
MOV, MVN
Przenieś
Menedżer zasobów! = PC, usług pulpitu zdalnego! = komputera
LDR, LDR [S] B, H LDR [S]
Ładowanie z pamięci
Ale nie LDR literału formularzy
STRH STR, CIĄG_B,
Przechowywania w pamięci
DODAJ ADC, RSB, SBC, SUB
Dodaj lub usuń
Ale nie SP Dodaj/SUB, SP, formularze imm7
Menedżer zasobów! = PC, Rdn! = PC i model Rdm! = komputera
CMP, CMN
Porównaj
Menedżer zasobów! = PC, Rn! = komputera
MUL
Masowo
AUTOMATYCZNEGO ODZYSKIWANIA SYSTEMU, LSL, LSR, ROR
Bitowe shift
I ORR KOD, EOR, TST
Operatory arytmetyczne
BX
Odgałęzienie do zarejestrowania
Menedżer zasobów! = komputera
Mimo że bieżący procesorów ARMv7 nie można zgłosić stosowanie niedozwolonych instrukcji formularzy, przyszłych generacji powinny.Jeśli formularze te zostaną wykryte, dowolny program, który używa tych może zostać rozwiązana z wyjątkiem Niezdefiniowany instrukcji.
Instrukcje SDIV/UDIV
Korzystanie z liczbą całkowitą podzielić instrukcje SDIV i UDIV jest w pełni obsługiwana, nawet na platformach bez macierzystego sprzętu do ich obsługi.Obciążenie na dzielenie SDIV lub UDIV przy użyciu procesora Cortex A9 jest około 80 cykle, oprócz całkowity czas dzielenie cykli 20 250, w zależności od danych wejściowych.
Rejestruje liczba całkowita
Procesor ARM obsługuje 16 rejestruje liczbę całkowitą:
Rejestruj |
Lotnych? |
Rola |
---|---|---|
r0 |
Lotne |
Parametr, wynik, zarejestruj zapasowy 1 |
R1 |
Lotne |
Parametr, wynik, zarejestruj zapasowy 2 |
R2 |
Lotne |
Parametr, zarejestruj zapasowy 3 |
R3 |
Lotne |
Parametr, zarejestruj zapasowy 4 |
R4 |
Bez trwałej |
|
R5 |
Bez trwałej |
|
R6 |
Bez trwałej |
|
R7 |
Bez trwałej |
|
R8 |
Bez trwałej |
|
R9 |
Bez trwałej |
|
R10 |
Bez trwałej |
|
R11 |
Bez trwałej |
Wskaźnik ramki |
R12 |
Lotne |
Zarejestruj się wewnątrz wywoływania zapasowy |
R13 (SP) |
Bez trwałej |
Wskaźnik stosu |
R14 (LR) |
Bez trwałej |
Zarejestruj się łącze |
R15 (PC) |
Bez trwałej |
Licznik programu |
Aby uzyskać szczegółowe informacje na temat korzystania z parametru i zwrócić wartość rejestruje, zobacz sekcję przekazywania parametrów w tym artykule.
System Windows wykorzystuje r11 dla przyspieszenia miejscu ramki stosu.Aby uzyskać więcej informacji zobacz sekcję chodzenie stosu.Z tego powodu r11 musi wskazywać łącze znajdujące się najwyżej w łańcuchu we wszystkich przypadkach.Nie używaj r11 w ogólnych zastosowaniach — kod nie generuje przeprowadzi poprawne stosu podczas analizy.
Rejestruje VFP
System Windows obsługuje tylko wariantów ARM, które mają coprocessor VFPv3 D32 pomocy technicznej.Oznacza to zmiennoprzecinkowych rejestrów zawsze są obecne i może być korzystali z parametru przekazywania i pełny zbiór 32 rejestruje jest dostępny do użycia.Rejestruje VFP i przedstawiono ich użycia w tej tabeli:
Wybiera |
podwojenia |
Quads |
Lotnych? |
Rola |
---|---|---|---|---|
s0 s3 |
D0 d1 |
q0 |
Lotne |
Parametry, wynik, zapasowy rejestru |
S4 s7 |
d2 d3 |
1. |
Lotne |
Zarejestruj się parametry zapasowy |
s8 s11 |
D4 d5 |
2 kwartał |
Lotne |
Zarejestruj się parametry zapasowy |
S12 s15 |
D6 d7 |
Q3 |
Lotne |
Zarejestruj się parametry zapasowy |
S16 s19 |
D8 d9 |
kwartał 4 |
Bez trwałej |
|
S20 s23 |
D10 d11 |
Q5 |
Bez trwałej |
|
S24 s27 |
D12 d13 |
Q6 |
Bez trwałej |
|
S28 s31 |
D14 d15 |
Q7 |
Bez trwałej |
|
D16 d31 |
Q8 q15 |
Lotne |
W następnej tabeli przedstawiono zmiennoprzecinkowych stanu i kontroli zarejestrować bitfields (FPSCR):
Bity |
Znaczenie |
Lotnych? |
Rola |
---|---|---|---|
31-28 |
NZCV |
Lotne |
Flagi stanu |
27 |
QC |
Lotne |
Skumulowany nasycenie |
26 |
AHP |
Bez trwałej |
Alternatywne kontroli pół podwójnej precyzji |
25 |
NAZWA WYRÓŻNIAJĄCA |
Bez trwałej |
Domyślna NaN tryb sterowania |
24 |
FZ |
Bez trwałej |
Kontrola tryb Wyczyść do zera. |
23-22 |
RMode |
Bez trwałej |
Tryb kontroli zaokrąglenia |
21-20 |
Krok |
Bez trwałej |
Krok wektora, zawsze musi mieć wartość 0 |
18-16 |
Dług |
Bez trwałej |
Długość wektora, zawsze musi mieć wartość 0 |
15, 12-8 |
Środowisko IDE, IXE itp. |
Bez trwałej |
Wyjątek pułapek Włącz bitów, zawsze musi mieć wartość 0 |
7, 4-0 |
IDC, IXC itp. |
Lotne |
Flagi wyjątek zbiorcza |
Wyjątki zmiennoprzecinkowa
Większość sprzętu ARM nie obsługuje IEEE zmiennoprzecinkowych wyjątków.Na wariantów procesora, które mają wyjątki zmiennoprzecinkowych sprzętu jądra systemu Windows połowy w trybie dyskretnym wyjątków i niejawnie wyłącza je w rejestrze FPSCR.Zapewnia to zachowanie znormalizowana przez procesor wariantów.W przeciwnym razie kod opracowany na platformie, którym nie obsługuje wyjątek otrzymać nieoczekiwanego wyjątku jest uruchomiona na platformie zawierającej obsługi wyjątków.
Przekazywanie parametru
Bez variadic funkcji, systemu Windows w imieniu ABI regułom ARM dla parametru przekazywania — dotyczy to również rozszerzenia VFP i zaawansowane SIMD.Wykonaj te reguły standardowego wywołania procedury dla architektury ARM, skonsolidowany z rozszerzeniami VFP.Przez domyślny, pierwszy argumenty cztery całkowitą i maksymalnie osiem zmiennoprzecinkowych lub wektorową argumenty przekazywane do rejestru i dodatkowe argumenty przekazywane na stosie.Argumenty są przypisane do rejestrów lub stosu za pomocą tej procedury:
Etap A — inicjowania
Inicjowanie jest wykonywane tylko raz, przed rozpoczęciem przetwarzania argument:
Następny podstawowych zarejestrować numer (NCRN) jest ustawiona na r0.
Rejestruje VFP są oznaczone jako nieprzydzielonego.
Następny skumulowany argumentu Adres (NSAA) ma ustawioną wartość bieżącej SP.
Jeśli zostanie wywołana funkcja, która zwraca wynik w pamięci, adres wynik jest umieszczany w r0 i NCRN ma ustawioną wartość r1.
Etap B — Pre dopełnienia i rozszerzenia argumentów
Dla każdego argumentu na liście jest stosowana pierwszą regułę zgodnych z poniższej listy:
Jeśli argument jest typu złożonego, rozmiar, którego nie można określić statycznie zarówno przez obiekt wywołujący i wywoływany, argument jest skopiowany do pamięci i zastępuje wskaźnik do kopiowania.
Jeśli argument jest bajty lub 16-bitowe pół word, następnie jest rozszerzony zero lub rozszerzony logowania do pełnego wyrazu 32-bitowych i traktowane jako argumentu 4 bajtów.
Jeśli argument jest typu złożonego, jego rozmiar jest zaokrąglona do najbliższej wielokrotności 4.
Etap C — przypisania argumentów rejestrów i stos
Dla każdego argumentu na liście następujące zasady są stosowane z kolei, dopóki przydzielone argument:
Jeśli argument jest typu VFP i jest wystarczająco dużo kolejne nieprzydzielonego rejestruje VFP odpowiedniego typu, argument jest przydzielany do najniższej numer sekwencji takich rejestrów.
Jeśli argument jest typem VFP, wszystkie pozostałe rejestry nieprzydzielonego są oznaczone jako niedostępny.NSAA jest dostosowywany do góry, dopóki nie jest ustawione poprawnie dla typu argument i argument są kopiowane do stosu w skorygowaną NSAA.NSAA jest zwiększana o wielkości argument.
Jeśli argument wymaga wyrównanie 8 bajtów, NCRN jest zaokrąglona do następnej liczby nawet rejestru.
Jeśli rozmiar argumentu w 32-bitowy słowa nie ma więcej niż r4 minus NCRN, argument jest skopiowane do rejestrów podstawowe, począwszy od NCRN, z co najmniej znaczących bitów, zajmujące rejestruje niższym indeksie.NCRN jest zwiększany przez liczbę rejestry używane.
Jeśli NCRN jest mniejsza niż r4 i NSAA jest taki sam, jak PS, argument jest dzielony między rejestrów podstawowych i stosu.Pierwsza część argumentu są kopiowane do rejestrów podstawowe, począwszy od NCRN do i tym r3.Pozostała część argument są kopiowane na stosie, począwszy od NSAA.NCRN ma ustawioną wartość r4 i NSAA jest zwiększany przez rozmiar argumentu minus kwota przekazana do rejestru.
Jeśli argument wymaga wyrównanie 8 bajtów, NSAA jest zaokrąglona do następnego adresu wyrównane 8 bajtów.
Argument jest kopiowany do pamięci pod adresem NSAA.NSAA jest zwiększany przez rozmiar argumentu.
Rejestruje VFP nie są używane w różnych funkcjach variadic i reguły etapu C 1 i 2 są ignorowane.To oznacza, że może zaczynać się od opcjonalne wypychania {r0-r3} być dołączana argumenty rejestru do wszelkie dodatkowe argumenty przekazane przez obiekt wywołujący funkcję variadic, a następnie przejść do listy cały argument bezpośrednio ze stosu.
Wartości typu Liczba całkowita są zwracane w r0, opcjonalnie rozszerzone r1 dla wartości zwracanych w 64-bitowych.Wartości typu SIMD lub VFP/NEONU zmiennoprzecinkowe są zwracane w s0, d0 lub q0, zgodnie z potrzebami.
Stos
Stos muszą pozostać 4 bajty wyrównane przez cały czas i musi być 8 bajty wyrównane na granicach żadnych funkcji.Jest to wymagane do obsługi często zazębione operacji na stosie 64-bitowych zmiennych.ARM EABI informujący o stosu 8 bajty wyrównane na dowolnego interfejsu publicznego.W celu zachowania spójności systemu Windows na ARM ABI traktuje dowolne obramowanie funkcji jako publiczny interfejs.
Funkcje, które mają używania wskaźnik ramki — na przykład funkcje tego wywołania alloca lub zmienić wskaźnik stosu dynamicznie — należy ustawić wskaźnik ramki w r11 w funkcji prologu i pozostaw ją bez zmian do epilogu.Funkcje, które nie wymagają wskaźnik ramkę, należy wykonać wszystkie aktualizacje stosu w prologu i pozostać bez zmian do epilogu wskaźnik stosu.
Funkcje, które Przydziel 4 KB lub więcej na stosie należy upewnić się, że każdej strony przed ostatniej stronie jest dotknięciu w kolejności.Zapewnia to, że kod nie może "leap powyżej" stron ochronę, które system Windows wykorzystuje do rozszerzenia stosu.Zazwyczaj jest to wykonywane przez __chkstk pomocnika, który został przekazany alokacji stosu całkowita liczba bajtów, podzielona przez 4 w r4, a które zwraca ilość alokacji końcowego stosu w bajtach, po powrocie do r4.
Strefa czerwony
Obszar 8 bajtów bezpośrednio pod wskaźnika bieżącego stosu jest zarezerwowany do analizy i poprawianie dynamicznych.Pozwala to na dokładnie wygenerowanego kodu ma zostać wstawiony, którym są przechowywane 2 rejestruje w [sp # 8] i tymczasowo używa ich do celów dowolnego elementu.Jądra systemu Windows gwarantuje, że te 8 bajtów nie zostaną zastąpione w przypadku wyjątku lub przerwania zarówno w trybie użytkownika, jak i trybie jądra.
Stos jądra
Domyślny tryb jądra stosu w systemie Windows jest trzech stron (12 KB).Należy zachować ostrożność nie utworzyć funkcje, które mają buforów dużą stosu w trybie jądra.Przerwania może pochodzić się przy użyciu bardzo mało wysokość stosu i spowodować, że wyniki alarm operacji w stosie.
Charakterystykę języka C/C++
Wyliczenia to typy 32-bitowa wartość całkowita, chyba że co najmniej jedną wartość w wyliczeniu wymaga 64-bitowym słowa liczba o podwójnej precyzji magazynu.W takim przypadku wyliczanie będzie przeniesiony do typu Liczba całkowita 64-bitowych.
wchar_t jest zdefiniowany jako równoważne unsigned short, aby zachować zgodność z innych platform.
Stos chodzenie
Kod systemu Windows została skompilowana z wskaźniki ramki włączone (/Oy (Pominięcie wskaźnika ramki)) umożliwiające chodzenie szybkie stosu.Ogólnie rzecz biorąc, zarejestruj się r11 punktów do następnego łącza w łańcuchu, który jest {r11, lr} pary, który określa wskaźnik do poprzedniej ramki stosu i adres zwrotny.Zaleca kodu również włączania wskaźniki ramki na lepsze profilowania i śledzenia.
Wyjątek Unwinding
Stos unwinding podczas obsługi wyjątku jest włączone za pomocą kodów unwind.Kody unwind są sekwencję bajtów zapisanych w sekcji .xdata pliku wykonywalnego obrazu.Odzwierciedlać operację kodu prologu i epilogu funkcji w sposób ogólny, aby skutki prologu funkcji można cofnąć w ramach przygotowania do unwinding do wywołującej ramki stosu.
ARM EABI określa modelu unwinding wyjątek, który używa rozwijają się kody.Jednak ta specyfikacji nie jest wystarczająca do unwinding w systemie Windows, który musi obsługiwać przypadki, w którym procesor jest w trakcie prologu i epilogu funkcji.Aby uzyskać więcej informacji na temat systemu Windows na ARM wyjątku i unwinding zobacz ARM Exception Handling.
Zaleca się, że dynamicznie wygenerowanego kodu można opisane przy użyciu dynamicznych funkcji tabel w wywołania RtlAddFunctionTable i skojarzonych z nim funkcje, tak aby wygenerowany kod może wprowadzać obsługi wyjątków.
Licznik cyklu
Procesory ARM z systemem Windows są wymagane do obsługi licznik cyklu, ale bezpośrednio za pomocą licznika może powodować problemy.Aby uniknąć tych problemów, systemu Windows w imieniu żądania znormalizowaną wartość licznika cyklu 64-bitowych przy użyciu Niezdefiniowany kod operacji.C lub C++, użyj __rdpmccntr64 wewnętrznej, aby emitować odpowiedni kod operacji, z zestawu, użyj __rdpmccntr64 instrukcji.Odczytywanie licznik cyklu ma około 60 cykli na Cortex A9.
Ten licznik jest licznikiem true cyklu, nie zegara; w związku z tym zliczania częstotliwość zależy od częstotliwości procesora.Pomiar czasu czas zegara, należy użyć QueryPerformanceCounter.
Zobacz też
Informacje
Typowe problemy przy migracji Visual C++ ARM