Udostępnij za pośrednictwem


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:

  1. Następny podstawowych zarejestrować numer (NCRN) jest ustawiona na r0.

  2. Rejestruje VFP są oznaczone jako nieprzydzielonego.

  3. Następny skumulowany argumentu Adres (NSAA) ma ustawioną wartość bieżącej SP.

  4. 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:

  1. 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.

  2. 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.

  3. 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:

  1. 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.

  2. 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.

  3. Jeśli argument wymaga wyrównanie 8 bajtów, NCRN jest zaokrąglona do następnej liczby nawet rejestru.

  4. 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.

  5. 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.

  6. Jeśli argument wymaga wyrównanie 8 bajtów, NSAA jest zaokrąglona do następnego adresu wyrównane 8 bajtów.

  7. 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

Koncepcje

ARM Exception Handling