Programowanie w asemblerze ARM wprowadzenie 17 stycznia 2017
Historia Firma ARM Ltd. powstała w 1990 roku jako Advanced RISC Machines Ltd., joint venture firm Acorn Computers, Apple Computer i VLSI Technology. Majatkiem firmy jest własność intelektualna, mówi się że jest fabless (od fabricate): nie produkuje sama żadnych układów. Firma zajmuje się projektowaniem procesorów rodziny ARM. Projekty licencjonuje firmom partnerskim, które produkuja układy i sprzedaja je. Dzięki temu firma kontroluje architekturę ARM.
Historia Procesor ARM powstał w 1983 roku w angielskiej firmie Acorn, na potrzeby komputera o tej samej nazwie. Ponieważ żaden z istniejacych procesorów 16-bitowych nie spełniał postawionych wymagań, więc zaprojektowano własny procesor 32-bitowy. Podobno był to pierwszy komercyjny RISC.
Historia Inne firmy zainteresowały się tym procesorem. Apple potrzebowało procesora do projektu PDA (późniejszego Newton MessagePad). Spowodowało to odłaczenie się grupy procesorowej od firmy Acorn i utworzenie firmy Advanced RISC Machines Ltd.
ARM Rynek (tanich) procesorów wbudowanych (embedded) 2 mld procesorów w 2005 Telefony komórkowe, modemy, układy hamulcowe w samochodach Cała rodzina procesorów projektów dopasowanych do różnych potrzeb Ponad 50 wspieranych systemów operacyjnych. ARM core to często fragment większego układu, sprzedawanego przez ostatecznego producenta
Architektura Obecnie istnieje osiem podstawowych wersji architektury. Każda wersja jest oparta na poprzedniej. Numery wersji architektury to nie to samo co numery modeli, np. modele układu ARM9 moga realizować wersję ARMv4 lub ARMv5.
Architektura Procesor w zasadzie 32-bitowy, ale Dwa zestawy instrukcji: ARM (32 bity) i Thumb (16 bitów) Dzięki temu w razie potrzeby mniejsza zajętość pamięci Brak dzielenia, symulowane programowo Brak liczb zmiennopozycyjnych, symulowane programowo Rozszerzenia do przetwarzania sygnałów (DSP Digital Signal Processing) Wydajna obsługa wyjatków.
RISC Architektura RISC (Reduced Instruction Set Computer) Proste instrukcje jednakowej długości, mniej klas instrukcji Jednakowy czas wykonania: jeden cykl = jedna instrukcja Przetwarzanie potokowe, wiele rejestrów Wszystkie rejestry uniwersalne, architektura load-store Złożoność w kompilatorze, a nie w procesorze Bezpośrednia realizacja bez mikroprogramowania Złożone operacje (np. dzielenie) wykonywane programowo
Architektura ARM Oparta na koncepcji RISC, ale nieco inne priorytety Zmniejszenie zużycia pradu, bo zwykle zasilanie z baterii Duża gęstość upakowania instrukcji, bo często ograniczona pamięć Zmniejszenie rozmiaru obszaru układu zajętego przez procesor, w układach single-chip daje więcej miejsca na inne elementy Ograniczenia na koszt
Architektura ARM Różnice względem czystego RISC Zmienny czas wykonania dla niektórych instrukcji, np. load-store-multiple ładujaca ciag komórek pamięci do kolejnych rejestrów Układ przesuwania dla jednego z rejestrów wejściowych wydłuża czas wykonania instrukcji Alternatywny 16-bitowy zestaw instrukcji Thumb Instrukcje wykonywane warunkowo Rozszerzone instrukcje do DSP (np. 16x16 bitów mnożenie i saturacja)
Architektura ARM Szyny z protokołem AMBA (Advanced Microcontroller Bus Architecture) Wszystkie urzadzenia odwzorowane na pamięć (memory-mapped) dostęp do rejestrów urzadzenia jak do komórek pamięci zbędne dodatkowe instrukcje
ISA Rejestry 32-bitowe Instrukcje obliczeniowe: 2 rejestry źródłowe + rejestr wynikowy 7 trybów pracy, normalny to user.
Rejestry Dla trybów user i system 16 aktywnych rejestrów uniwersalnych r0-r15 oraz rejestr stanu procesora cpsr. Niektóre rejestry maja specjalne przeznaczenie i dodatkowe nazwy r13 (sp) stack pointer: wskaźnik wierzchołka stosu r14 (lr) link register: do przechowania adresu powrotnego przy wywołaniu procedury r15 (pc) program counter: licznik instrukcji Istnieja instrukcje, które w sposób specjalny traktuja r14 i r15.
Rejestr stanu procesora Dwa rejestry stanu procesora Pola: cpsr current program status register: bieżacy rejestr stanu spsr saved program status register: zapamiętany rejestr stanu, dostępny tylko w trybach uprzywilejowanych. 4 flagi dla wyniku operacji: N, Z, C, V Dodatkowe flagi w niektórych modelach J (Jazelle) do wykonywania 8-bitowych instrukcji Javy Q dla saturacji przy rozszerzeniach DSP Tryb pracy procesora Dwie maski do przerwań I i F (zwykłe i szybkie przerwania) T : wybór zestawu Thumb
Tryby pracy procesora user (usr): nieuprzywilejowany system (sys): jak user, ale można dowolnie zmieniać rejestr stanu abort (abt): po błędnym odwołaniu do pamięci undefined (und): po napotkaniu niezdefiniowanej lub niezaimplementowanej instrukcji fast interrupt request (fiq) i interrupt request (irq): dla dwóch poziomów przerwań supervisor (svc): poczatkowy stan, używany także dla jadra systemu operacyjnego i po reset. Dodatkowe prywatne banki rejestrów dla trybów uprzywilejowanych, zastępuja rejestry r13, r14, a dla szybkich przerwań także r8-r12. Dodaja rejestr spsr.
Instrukcje Zaczniemy od najprostszej instrukcji. MOV r0,r1 MOV r4,#10 Wpisuje ona do rejestru zawartość innego rejestru lub stała. Sufiks S powoduje ustawianie flag, nawet w instrukcji MOV MOVS r0,r1
Instrukcje Drugi (lub jedyny) argument instrukcji może być dodatkowo obrócony lub przesunięty, np. instrukcja MOV r0,r1,lsl #2 odpowiada instrukcji przesunięcia zawartości r1 w lewo o 2 bity z zapisaniem wyniku w r0. Inny przykład z wyliczonym przesunięciem: MOV r0,r1,asr r3
Skok wyliczany Jeśli rejestrem wynikowym instrukcji (nie tylko MOV!) jest pc, to działa ona jak skok pod wyliczony adres, na przykład MOV pc,r1 Jeśli r1 zawiera adres tablicy skoków, to żeby wybrać jeden z nich ADD pc,r1,r2 LSL #2 W takiej sytuacji flagi wolno ustawiać tylko w trybach uprzywilejowanych.
Wykonanie warunkowe Większość instrukcji może mieć sufiks ograniczajacy (flagami stanu), kiedy będa one wykonane, np. instrukcja MOVEQS r0,r1,asr r3 będzie wykonana tylko wtedy, gdy flaga zera jest ustawiona (a sama przestawi flagi). Niektóre dostępne sufiksy: AL (always, domyślny), EQ, NE, GT, LE, LT, GE, MI, PL.
Wykonanie warunkowe Przykład: obliczanie GCD dwóch liczb całkowitych define function gcd (a :: <integer>, b :: <integer>) => (r :: <integer>) while (a ~= b) if (a > b) a := a - b; else b := b - a; end if; end while; a end function;
Wykonanie warunkowe W asemblerze zakładamy, że argumenty sa w rejestrach r0 i r1, a wynik ma być w r0. bez wykonania warunkowego gcd CMP r0,r1 BEQ koniec BLT mniejsze SUB r0,r0,r1 B gcd mniejsze SUB r1,r1,r0 B gcd koniec BX lr ;???
Wykonanie warunkowe z wykonaniem warunkowym gcd CMP r0,r1 SUBGT r0,r0,r1 SUBLT r1,r1,r0 BNE gcd BX lr ;???
Instrukcje arytmetyczne Dodawanie i odejmowanie liczb całkowitych ze znakiem i bez znaku, pierwszy argument musi być rejestrem. ADD r0,r1,r1,lsl #1 ;mnożenie przez 3 Instrukcje odwróconego odejmowania RSB r0,r1,#0 ;negacja RSC r4,r1,r2,lsl #1
Instrukcje logiczne Typowe operacje: AND, ORR (inclusive-or), EOR (exclusive-or) BIC (BIt Clear): czyści w pierwszym argumencie bity wskazane drugim argumentem BIC r0,r1,#3 Negacja jako MVN: neguje bitowo argument i zapisuje do wyniku.
Instrukcje porównania Typowe operacje: porównanie arytmetyczne CMP i logiczne TST, wynik tylko we flagach rejestru stanu procesora TEQ (test na równość): używa XOR TEQ r1,#3
Mnożenie MUL: zwyczajne mnożenie. MLA: mnożenie z akumulacja wyniku, 3 argumenty. Mnożymy dwa pierwsze argumenty i otrzymany iloczyn dodajemy do trzeciego argumentu. Długie instrukcje mnożenia: SMLAL, SMULL, UMLAL, UMULL. Cztery argumenty, pierwsze dwa po sklejeniu sa 64-bitowym miejscem na wynik.
Przykład AREA.text,CODE,READONLY EXPORT square ;int square (int i) square MUL r1,r0,r0 MOV r0,r1 MOV pc,lr ;return END Konwencja: wynik w r0, argumenty w r0, r1,... Do powrotu z procedury zamiast MOV można użyć BX lr
Sterowanie Rejestr r15 ma też druga nazwę: pc. Zwykle używa się tej drugiej nazwy, napotkanie w naturze r15 jest mało prawdopodobne. Jest to bowiem licznik instrukcji (znany w gwarze x86 jako ip instruction pointer). Normalnie (gdy nie ma skoku ani wywołania funkcji) rejestr ten zwiększany jest o 4 po wykonaniu każdej instrukcji.
Skok bezwarunkowy (i bezsensowny).text.global main main: mov r0, #2 b end mov r0, #3 end: bx lr