Programowanie w asemblerze Uwagi o ARM
Transkrypt
Programowanie w asemblerze Uwagi o ARM
Programowanie w asemblerze Uwagi o ARM Zbigniew Jurkiewicz, Instytut Informatyki UW 17 stycznia 2017 Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Organizacja pamieci ˛ Trzy możliwości Dostep ˛ bezpośredni do pamieci ˛ fizycznej, brak zarzadzania. ˛ Używane w mikrokontrolerach. MPU (Memory Protection Unit): podział pamieci ˛ na regiony, ochrona dostepu ˛ (uprawnienia). MMU (Memory Management Unit): pamieć ˛ wirtualna. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Architektura wersja 5 v5T: nadzbiór ARMv4T. Nowe instrukcje: BLX, CLZ i BKPT. v5TE Nowe instrukcje do cyfrowego przetwarzania sygnałów. Nowe instrukcje mnożenia dla DSP: SMULxy, SMLAxy, SMULWy, SMLAWy i SMLALxy. Arytmetyka z nasyceniem: flaga Q, instrukcje QADD, QSUB, QDADD i QDSUB. Pre-load hinty dla ładowania z pamieci. ˛ v5TEJ: przyśpieszenie sprz˛etowe dla jezyka ˛ Java. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Architektura wersja 6 v6 Obsługa danych „mixed endian”: SETEND, REV, REV16, REVSH. Ponad 60 nowych instrukcji SIMD, np. SMUSD, SMUADX, USAD8, USADA8. Ładowanie danych niewyrównanych. Nowe instrukcje synchronizacji: LDREX, STREX. v6T2 z Thumb-2: rozszerzona, kompletna wersja Thumb. „Zwiastun” nowej architektury Cortex dla profilu wbudowanego ARMv6M. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM ARMv6 Instrukcje PKHBT i PKHTB do pakowania 16-bitowych liczb w jeden rejestr wynikowy (z dwóch rejestrów źródłowych). Mini-operacje wektorowe: dodawanie/odejmowanie par liczb 16-bitowych i czwórek liczb 8-bitowych, np. SADD16, USUB8. Te same operacje z odpowiednim nasyceniem, np. QADD8. Nasycanie do podanej liczby bitów SSAT r3,#8,r2 USAT r3,#12,r2,LSL #3 Instrukcje zamiany kolejności bajtów dla całego rejestru i dla dwóch połówek 16-bitowych: REV i REV16. Wybór „endianness” dla przesyłania danych SETEND BE SETEND LE Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM ARMv6 Nowe bity w rejestrze stanu: GE[3:0]: Dla SIMD, flaga wiekszy-lub-równy ˛ dla każdego 8/16-bitowego wycinka. E: Aktualny ustawienie „endianness”, można zmieniać przez SETEND. A: maskowanie imprecise data abort exceptions Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Tasowanie Trzy nowe instrukcje (wszystkie z wykonaniem warunkowym): REV r1,r2 Odwraca kolejność bajtów. REV16 r1,r2 Odwraca kolejność bajtów w pierwszej i drugiej parze. REVSH r1,r2 Zamienia miejscami dwa dolne bajty, po czym rozszerza bit znaku. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Synchronizacja Dwie nowe instrukcje: LDREXww r1,[r2] Ładuje z pamieci ˛ do rejestru, po czym ustawia monitor „obserwujacy” ˛ ten adres. STREXww r0,r1,[r2] Zapisuje r1 do pamieci ˛ i zwraca w r0 sukces, jeśli w miedzyczasie ˛ nie było innych zapisów ani odczytów. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Architektura wersja 7 Nazwana „Cortex core” (wszystkie poprzednie to „ARM core”). v7A, v7R Dynamic Compiler Support. Execution Environment (Thumb-2EE). VFP v3 (Vector Floating Point). NEON advanced SIMD. Thumb-2 obowiazkowo. ˛ v7M Minimalna wersja dla zastosowań wbudowanych. Tylko instrukcje Thumb-2. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Architektura wersja 7 Uniwersalny asembler, tłumaczacy ˛ podobno na oba zestawy bazowych instrukcji Technologia NEON to 64/128-bitowa zaawansowana architektura SIMD do przyśpieszenia aplikacji multimedialnych i DSP. Daje dla nich co najmniej 3-krotne przyśpieszenie wzgledem ˛ ARMv5 i dwukrotne wzgledem ˛ ARMv6. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Zestawy instrukcji Bazowy 32-bitowy zbiór instrukcji ARM Ograniczony 16-bitowy zbiór Thumb (mała zajetość ˛ pamieci) ˛ Nowy mieszany 16/32-bitowy zestaw Thumb-2 Jazelle DBX do bajtkodów Javy Zestaw NEON do 64/128-bitowego SIMD Zestaw VFP do wektorowego przetwarzania liczb zmiennopozycyjnych. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Dodatkowe opcje/zestawy instrukcji TrustZone: podział procesora na dwie cz˛eści: zaufana˛ i nie. Jazelle: opkody dla maszyny Javy, deprecated. SIMD: wiadomo. Proste operacje. NEON: advanced SIMD. VFP: (wektorowa) arytmetyka rzeczywista. CRYPTO: elementarne wsparcie dla kryptografii Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM NEON Termin NEON oznacza osobny zestaw instukcji do Advanced SIMD, dodawany do bazowego zestawu. Używa koprocesorów 10 i 11, tych samych co VFP. Jeśli oba rozszerzenia obecne, to dziela˛ rejestry, ponadto VFP zyskuje dodatkowe. 32 rejestry 64-bitowe: d0–d15 Można je łaczyć ˛ w pary, otrzymujac ˛ 16 rejestrów 128-bitowych q0–q15. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM NEON: instrukcje W asemblerze GNU trzeba podać opcje˛ -mfpu=neon ładowanie kilku rejestrów z pamieci ˛ vld1.8 d0.d1.d2,[r0] z przeplotem vld3.8 d0.d1.d2,[r0] zapis analogicznie (vst). Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM NEON: instrukcje Dodawanie wektorowe vadd.i32 q0,q0,q0 Dla C zdefiniowano intrinsics: #include <arm_neon.h> uint32x4_t double_elements (uint32x4_t input) { return vaddq_u32(input, input); } Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Wsparcie dla kryptografii Elementarne instrukcje, do prostych zastosowań. 2 instrukcje encode/decode dla AES, działaja˛ na 128-bitowych rejestrach Advanced SIMD. Wsparcie dla SHA-1 i SHA-256 Running hash trzymany w 2 128-bitowych rejestrach. Instrukcje haszujace ˛ w jednym kroku po 4 nowe słowa danych. Instrukcje do przyśpieszenia generowania kluczy. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Architektura wersja 8 Wyraźny podział na profile: ARMv8-A application profile: „platformy” obliczeniowe, wydajność. ARMv8-R real-time profile: wbudowane aplikacje o określonym czasie reakcji (samochody, sterowanie przemysłowe). ARMv8-M embedded profile: mikrokontrolery itp. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Application Profile ARMv8-A 32 bity i 64 -bity 3 zestawy instrukcji: A32, T32 i A64. Pamieć ˛ wirtualna Mocne systemy operacyjne Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Real-time Profile ARMv8-R 32 bity 2 zestawy instrukcji: A32 i T32s Protected memory system (pamieć ˛ wirtualna opcjonalnie) Zoptymalizowany na systemy czasu rzeczywistego Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Microcontroller Profile ARMv8-M 32 bity Tylko zestaw instrukcji T32/Thumb Protected memory system ??? Zoptymalizowany na mikrokontrolery Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM AArch64: organizacja 31 uniwersalnych rejestrów 64-bitowych (X0 – X30) Licznik rozkazów (PC) i wskaźnik stosu (SP) nie sa˛ rejestrami uniwersalnymi Dedykowany rejestr z zerem dostepny ˛ dla wiekszości ˛ instrukcji. 32- lub 64-bitowe argumenty instrukcji Duża pamieć ˛ wirtualna, adresy 64-bitowe (w teorii) Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM AArch64: organizacja Wszystkie rejestry wektorowe 128-bitowe: Vx[127:0] Zmiennopozycyjna arytmetyka skalarna używa dolnych 64 (double) lub 32 (single precision) bitowe Zgodnośc z IEEE: tryby zaokraglania, ˛ denormalizacja, NaN. MMU: tylko 48 bitów adresu. Górne 8 wolne np. na tagged pointers. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM AArch64: organizacja 4 poziomy uprzywilejowania (wyjatków), ˛ EL3 najbardziej uprzywilejowany EL3: EL2: EL1: EL0: (TrustZone) Monitor Virtual Machine Monitor lub nic Guest OS lub Secure WorldOS App lub Trusted App Każdy poziom ma osobna˛ tablice˛ wektorów, wektor dla każdego typu: synchroniczne, IRQ, FIQ, System Error. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Narz˛edzia ARM Software Development Toolkit (SDT) — lekko przestarzały ARM Developer Suite (ADS) — też RealView Compiler Tools (RVCT) RealView Development Suite (RVDS) Inne firmy: Keil (obecnie w ARM), Green Hills i Metrowerks. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Narz˛edzia Kompilator C z ARM Developer Suite version 1.1 (ADS1.1) to armcc: armcc -c -o test.o test.c fromelf -text/c test.o > test.txt Jest też asembler aasm. arm-elf-gcc to kompilator GNU: arm-elf-gcc -fomit-frame-pointer -c -o test.o test.c arm-elf-objdump -d test.o > test.txt Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Uwagi ogólne C char jest unsigned, bo takie ładowanie z pamieci ˛ Unikać typów char i short dla liczników petli, ˛ bo trzeba w kodzie recznie ˛ badać zakresy (rejestry tylko 32-bitowe, wiec ˛ brak sygnalizacji przepełnienia/przeniesienia) Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Dzielenie Ponieważ dzielenie jest symulowane programowo, należy go unikać. Instrukcja C current = (current + increment) % size; zajmuje 50 cykli. Natomiast poniższy kod current += increment; if (current >= size) current -= size; zajmuje podobno tylko 3 cykle (dla armcc). Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Liczby rzeczywiste Standardowo brak sprz˛etowych liczb zmiennopozycyjnych, symulowane programowo W ARM7500FE jest Floating Point Accelerator (FPA). Jest też Vector Floating Point (VFP) akcelerator. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Asemblacja Asembler ARM to firmowo armasm. Użycie armcc -c main.c armasm proc.s armlink -o main.axf main.o square.o ARM ostatnio wprowadził nowa˛ wersje˛ składni, tzw. UAL (Unified Assembler Language), obejmujac ˛ a˛ zarówno ARM jak i Thumb i zdejmujac ˛ a˛ pewne ograniczenia na kolejność modyfikatorów instrukcji. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Składnia Dyrektywy ALIGN używa sie, ˛ żeby wyrównać do granic 4 bajtów, np. po napisie (ciagu ˛ znaków) DEFB służy do definiowania ciagów ˛ bajtów (także stringi) DEFW służy do definiowania słów (4 bajty). Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM C API Konwencje użycia rejestrów: ARM-Thumb Procedure Call Standard (ATPCS) r0–r3 (a1–a4): argumenty/wartości funkcji, kolejne argumenty na stosie, nie trzeba zachowywać r4–r8 (v1–v5): rejestry dla zmiennych, trzeba je zachowywać i odtwarzać r9 (v6, sb): rejestr dla zmiennych, w position independent kodzie adres bazy statycznej, adres bazy stosu (przy kontroli), trzeba zachowywać r10 (v7, sl): rejestr dla zmiennych, adres ograniczenia stosu (przy kontroli), trzeba zachowywać r11 (v8, fp): rejestr dla zmiennych, dawniej frame pointer, trzeba zachowywać r12 (ip): scratch register, nie trzeba zachowywać Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM C API Jeśli funkcja ma wiecej ˛ niż 4 argumenty, warto próbować cz˛eść z nich łaczyć ˛ w struktury. Argumenty 64-bitowe (long long, double) przekazywane w parach rejestrów. Zwracane w <r0,r1>. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Przykład ;; Hello World Version 2 B main hello DEFB goodbye DEFB ALIGN main "Hello World\n\0" "Goodbye Universe!\n\0" ADR R0,hello SWI ADR SWI SWI 3 R0,goodbye 3 2 ;get the start address of ;the "Hello World" string ;print the message ;point at the goodbye string ;print the message ;stop the program Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Inny przykład ;; Increment R0 until it reaches same value as in R1 ;; Then print a success message B fred ;nothing special about "main"! four DEFW 4 success DEFB "Register 0 has reached the value of \0" ALIGN fred LDR R1,four MOV R0,#1 next CMP R0,R1 BNE skip ADR R0,success SWI 3 MOV R0,R1 SWI 4 MOV R0,#10 SWI 0 SWI 2 skip ADD R0,R0,#1 B next ;LDR loads R1 with *contents* of location four ;put the value 1 (decimal) into R1 ;does R0 now have same number in it as R1 does? ;get start address of success message ;print the message ;move value from R1 into R0 for printing ;print the decimal value that is now in R0 ;stop the program Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Przekazywanie parametrów w kodzie Rejestr łacz ˛ acy ˛ upraszcza przekazywanie parametrów bezpośrednio w kodzie BL DCD DCD DCD Copy BufferLength Buffer1 Buffer2 ;długość w bajtach ;adres poczatkowy ˛ ;adres poczatkowy ˛ Po wywołaniu rejestr łacz ˛ acy ˛ zawiera adres poczatku ˛ bloku parametrów. Procedura (po ewentualnym zachowaniu rejestrów) pobiera parametry równocześnie ustawiajac ˛ rejestr łacz ˛ acy ˛ na właściwy adres Copy LDR LDR LDR R0,[LR],#4 R1,[LR],#4 R2,[LR],#4 Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Parametry na stosie (1) AREA |.text|,CODE,READONLY EXPORT sumof ; int sumof(int N, ...) RN 0 ;pierwszy parametr RN 1 ;suma (zainicjowana) n sum sumof SUBS n,n,#1 MOVLT sum,#0 SUBS n,n,#1 ADDGE sum,sum,r2 SUBS n,n,#1 ADDGE sum,sum,r3 MOV r2,sp ;gdy 0 elementów ;gdy jest drugi element ;gdy jest trzeci element ;do chodzenia po stosie Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Parametry na stosie (2) loop SUBS n,n,#1 LDMGEFD r2!,{r3} ADDGE sum,sum,r3 BGE loop MOV r0,sum MOV pc,lr END ;gdy jest kolejny element Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Wykonanie warunkowe Nastepuj ˛ acy ˛ kod w C if (c == ’a’) || c = ’e’ || c = ’i’ || c == ’o’) licznik++; może być zapisany bez instrukcji skoku TEQ r1,#’a’ TEQNE r1,#’e’ TEQNE r1,#’i’ TEQNE r1,#’o’ ADDEQ r2,r2,#1 ;r1=c ;r2=licznik Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Wykonanie warunkowe Zliczania liter w kodzie ASCII if ((c >= ’A’ && c <= ’Z’) || (c >= ’a’ && c <= ’z’) licznik++; można dokonać nastepuj ˛ aco ˛ (używajac ˛ porównań dla liczb bez znaku) SUB CMP SUBHI CMPHI ADDLS r3,r1,#’A’ r3,#’Z’-’A’ r3,r1,#’a’ r3,#’z’-’a’ r2,r2,#1 Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Pakowanie małych liczb Małe liczby całkowite można cz˛esto pakować parami do rejestrów, na przykład kod w C short index,increment; ... next = table[index]; index += increment; można zapisać nastepuj ˛ aco ˛ LDRB r2,[r4,r3,LSR #16] ADD r3,r3,r3,LSL #16 ;r2 = next ;r3 = index | increment gdzie to rejestr bazowy r4 zawiera adres tablicy table, zaś indeks bieżacy ˛ i krok sa˛ upakowane w r3. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM Pola bitowe Do wydobycia pola bitowego można oczywiście użyć maski wraz z instrukcja˛ AND Ale można też inaczej, np. dla bitów 4–8 z r1 MOV r2,r1,LSL #24 MOV r2,r2,LSR #28 Jeśli liczba ma być ze znakiem, to w drugiej instrukcji należy użyć ASR. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Uwagi o ARM