Asembler Arm64 dla Windows. Podstawowa wiedza w kapsułce
Spis treści
- Niejawny program testów Windows Insider
- Platforma chmurowa Azure
- Podstawy architektury Arm64 (AArch64)
-
Podstawy składni Microsoft Arm Assembler
- Stałe (EQU)
- Dane o rozmiarze bajta (DCB)
- Dane o rozmiarze pół słowa maszynowego (DCW, DCWU)
- Dane o rozmiarze słowa (DCD, DCDU)
- Dane o rozmiarze podwójnego słowa (DCQ, DCQU)
- Dane o rozmiarze wielu bajtów
- Etykiety (ang. labels)
- Proste operacje arytmetyczne
- Proste operacje logiczne
- Procedury (ang. procedures)
- Podstawowe instrukcje (A64)
Niejawny program testów Windows Insider
Program o nazwie Windows Insider pozwala na dostęp do przyszłych wersji systemu Windows, które można używać do celów testowych. Uczestnicy zapisani do niejawnego programu testów Windows Insider mogą bezpłatnie uzyskać pliki obrazu systemu Windows dla architektury Arm. Niestety próba instalacji systemu Windows dla Arm w oprogramowaniu typu emulator na sprzęcie x64 ze względu na niską wydajność takiego rozwiązania prawdopodobnie uniemożliwi normalne korzystanie z systemu.
Platforma chmurowa Azure
Wygodnym sposobem na uzyskanie dostępu do systemu Windows dla procesorów Arm (bez kupowania sprzętu) wydaje się być platforma chmurowa Azure. Należy jednak zaznaczyć, że jest to rozwiązanie płatne (nie licząc darmowych bonusowych śródków na start czy promocji).
Platformę sprzętową na której zainstalowano system Windows można odczytać np. za pomocą PowerShell.
Get-WmiObject -Class Win32_ComputerSystem | Select-Object -Property SystemType
Informacje o architekturze procesora można też znaleźć w oknie informacji o systemie (System > About).
Podstawy architektury Arm64 (AArch64)
Architektura sprzętowa Arm cały czas się rozwija, dlatego jej kolejne generacje nazywane są z użyciem numeru wersji np. Armv7, Armv8 czy Armv9. Procesory Arm obsługują kolejność bajtów LE oraz BE. System operacyjny Windows dla architektury Arm działa na kolejności bajtów LE. Warto wspomnieć, że nazwy AArch64 i AArch32 dotyczą stanu w jakim jest procesor (ang. execution state). Stan AArch64 (nazywany też Arm64) oznacza możliwość korzystania z 64-bitowych rejestrów oraz zestawu rozkazów A64. Natomiast stan AArch32 (nazywany Arm32) używa 32-bitowych rejestrów oraz zestawu rozkazów A32 oraz T32.
Dodatkowo architektura Arm definiuje następujące profile:
- Application (aplikacje),
- Real-time (czasu rzeczywistego),
- Microcontroller (mikrokontroler).
Dlatego często można spotkać zapis np. Armv9-A, który oznacza architekturę Arm dziewiątej generacji i profil Application.
Typy danych
- Bajt (8 bitów)
- Pół słowa maszynowego (16 bitów)
- Słowo maszynowe (32 bity)
- Podwójne słowo maszynowe (64 bity)
Stos programu
Format przykładowego rozkazu
Rejestry R0...R30
- Rejestr
X30
to Link Register (LR
), który przechowuje adres powrotny wymagany do powrotu z wywołania procedury. - Rejestr
X18
(XPR
) w trybie użytkownika (ang. user mode, ring 3) umożliwia dostęp do struktur TEB i PEB - Parametry wywoływanej procedury lub funkcji są przekazywane przez rejestry od
X0
doX7
. Jeśli parametrów jest więcej niż osiem, to pozostałe przekazywane są przez stos. - Wartości w postaci liczb całkowitych są zwracane w rejestrze
X0
. - Rejestry od
X19
doX28
oraz rejestrFP
są nieulotne (ang. nonvolatile), czyli jeśli są modyfikowane (używane), to ich wartości powinny zostać zachowane na początku funkcji i przywrócone przed wyjściem z funkcji. - Rejestry
X8
doX15
są ulotne (ang. volatile) — nie ma potrzeby zachowania ich wartości.
Rejestry od R0
do R30
są udostępniane w postaci:
W0...W30
(32 bitowe)X0...X30
(64 bitowe)
Rejestry V0...V31 oraz FPSR i FPCR
- Parametry wywoływanej procedury lub funkcji są przekazywane przez rejestry od
V0
doV7
. Jeśli parametrów jest więcej niż osiem, to pozostałe przekazywane są przez stos. - Wartości w postaci liczb zmiennoprzecinkowych są zwracane w rejestrze
V0
. - Młodsze 64-bity rejestrów od
V8
doV15
są nieulotne (ang. nonvolatile), czyli jeśli są modyfikowane (używane), to ich wartości powinny zostać zachowane na początku funkcji i przywrócone przed wyjściem z funkcji. - Rejestry
V16
doV31
są ulotne (ang. volatile) — nie ma potrzeby zachowania ich wartości.
Rejestry od V0
do V31
są udostępniane w postaci:
B0...B31
(8 bitowe)H0...H31
(16 bitowe)S0...S31
(32 bitowe)D0...D31
(64 bitowe)Q0...Q31
(128 bitowe)
Rejestry Z0...Z31
Rejestry od Z0
do Z31
są używane w rozkazach SVE.
Rejestr Program Counter
Rejestr PC
pozwala określić, która instrukcja jest następna do wykonania. Nie jest to rejestr ogólnego przeznaczenia. Rejestr PC
jest rejestrem specjalnym.
Rejestr Stack Pointer
Rejestr wskaźnika stosu. Nie jest to rejestr ogólnego przeznaczenia. Rejestr SP
jest rejestrem specjalnym.
Flagi NZCV
Flagi procesora nazywane też znacznikami to pola o rozmiarze jednego bitu, które mogą przyjmować wartość zero (flaga nieustawiona) lub jeden (flaga ustawiona).
-
N
(Negative) — Rezultat operacji jest wartością ujemną. Flaga ta jest ustawiana zgodnie z bitem znaku rezultatu (najstarszy bit). -
Z
(Zero) — Rezultat operacji jest równy zero. Flaga jest ustawiana np. gdy porównujemy dwie wartości i są one równe. Gdyż porównanie dwóch wartości to wykonanie odejmowania. Inny przykład to dekrementacja, czyli zmniejszanie wartości o jeden. Jeśli osiągniemy zero, to flaga jest ustawiana. -
C
(Carry) — Rezultat operacji spowodował przeniesienie (ang. carry). Przy użyciu rejestrówX0...X30
oznacza to, że rezultat nie mieści się w rejestrze (ma więcej niż 64 bity). -
V
(Overflow) — Rezultat operacji spowodował przepełnienie. Oznacza to, że rezultat nie mieści się w rejestrze oraz zmienił się najstarszy bit (nazywany bitem znaku).
Podstawy składni Microsoft Arm Assembler
Stałe (EQU)
Dyrektywa EQU
, której synonimem jest znak gwiazdki (*
) pozwala nadać wartości numerycznej przyjazną nazwę symboliczną.
Pozwala to uniknąć tzw. magic numbers, czyli wartości liczbowych, których znaczenie nie jest zrozumiałe bez zagłębienia się w dokumentację.
Prosty przykład: Wyświetlenie okna dialogowego przez funkcję MessageBox
. Jeśli jako rodzaj komunikatu poda się 0x00000002
,
to bez znajomości dokumentacji Windows API ciężko będzie się domyślić znaczenia tej wartości.
Natomiast utworzenie stałej nazwanej MB_ABORTRETRYIGNORE
pozwoli zwiększyć przejrzystość kodu.
Przykładowe stałe:
NULL EQU 0 ;stała NULL o wartości zero
TRUE EQU 1 ;stała TRUE o wartości jeden
FALSE EQU 0 ;stała FALSE o wartości zero
FALSE EQU 0 ;stała FALSE o wartości zero
LETTER_A EQU 'A' ;stała LETTER_A o wartości 0x41 (kod ASCII litery A)
Dane o rozmiarze bajta (DCB)
Dyrektywa DCB
, której synonimem jest znak równości (=
) pozwala zarezerwować jeden lub więcej bajtów z nadaną wartością początkową.
Za pomocą tego rodzaju dyrektywy możliwe jest również definiowanie napisów zakończonych zerem — nazywanych C string.
Jednak o kończący znak NULL
należy zadbać samemu.
format DCB "%#08x",0x00 ;przykładowy ciąg formatujący dla funkcji StringCChPrintf
var1 DCB 255 ;przykładowy bajt (8 bitów) o wartości 255 (0xFF)
var2 DCB 0xFF ;przykładowy bajt (8 bitów) o wartości 0xFF (255)
hello DCB "ethical.blue", 0xD, 0xA, "Magazine", 0x00 ;przykładowy napis ze znakiem nowej linii w środku
Dane o rozmiarze pół słowa maszynowego (DCW, DCWU)
Dyrektywa DCW
pozwala zarezerwować pół słowa maszynowego (16 bitów) lub więcej takich pół słów z nadaną wartością początkową.
Jeśli nie jest wymagane wyrównanie danych do 2 bajtów, to można zastosować dyrektywę DCWU
.
;pół słowa komputerowego (16 bitów, 2 bajty)
var1 DCW 0xBAD ;16 bitów (pół słowa komputerowego)
var2 DCWU 0xBAD ;16 bitów (pół słowa, bez wyrównania)
Dane o rozmiarze słowa (DCD, DCDU)
Dyrektywa DCD
pozwala zarezerwować słowo maszynowe (32 bity) lub więcej takich słów z nadaną wartością początkową.
Jeśli nie jest wymagane wyrównanie danych do 4 bajtów, to można zastosować dyrektywę DCDU
.
;Słowo (ang. word) na platformie Arm64 ma 32 bity (4 bajty).
;Natomiast słowo na platformie x64 ma 16 bitów (2 bajty).
var1 DCD 0xC0FFEE ;32 bity (słowo komputerowe)
var2 DCD 1,2,3,4 ;cztery słowa komputerowe (cztery razy 32-bity)
Dane o rozmiarze podwójnego słowa (DCQ, DCQU)
Dyrektywa DCQ
pozwala zarezerwować podwójne słowo maszynowe (64 bity) lub więcej takich podwójnych słów z nadaną wartością początkową.
Jeśli nie jest wymagane wyrównanie danych do 8 bajtów, to można zastosować dyrektywę DCQU
.
var1 DCQ 13 ;dane o rozmiarze 8 bajtów (64-bity)
Dane o rozmiarze wielu bajtów
Dyrektywy SPACE
oraz FILL
pozwalają zarezerwować wielobajtową przestrzeń z nadaną wartością początkową.
var1 SPACE 255 ;dane o rozmiarze 255 bajtów (wypełnione zerami)
var2 FILL 50,0xCC,1 ;dane o rozmiarze 50 bajtów wypełnione wartością 0xCC (1 to rozmiar wartości)
Etykiety (ang. labels)
Etykietami można oznaczać miejsca w kodzie programu, do których później można się odwoływać za pomocą określonych rozkazów. Pozwala to m.in. na zapętlanie fragmentów kodu czy przekazanie wykonania do fragmentu kodu i powrót za miejsce rozgałęzienia po wykonaniu.
W przypadku błędów budowania stosując Microsoft Arm Assembler (marmasm), należy pamiętać, że etykiety nie mają mieć wcięcia, natomiast mnemoniki powinny mieć wcięcie w postaci tabulatora lub znaków spacji.
AREA .drectve, DRECTVE
AREA .rdata, DATA, READONLY
EXPORT Main
IMPORT |__imp_ExitProcess|
AREA .text, CODE, ARM64
Main PROC
;odłożenie wartości rejestrów FR i LR na stosie programu
stp fp,lr,[sp,#-0x10]!
;zapisanie nowej wartości wskaźnika stosu (SP) w rejestrze FP
mov fp,sp
mov x0,#0 ;wyzerowanie rejestru X0
tst x0,x0 ;sprawdzenie czy w rejestrze X0 jest wartość zero
beq |FAIL| ;jeśli tak, to przejście do etykiety |FAIL|
b |EXIT| ;w przeciwnym wypadku bezwarunkowe przejście do |EXIT|
|FAIL|
mov w0,#-1 ;rejestr W0 przyjmuje wartość minus jeden
;będzie to kod powrotu funkcji ExitProcess
;zwracany do systemu Windows
|EXIT|
;wczytanie adresu funkcji ExitProcess do rejestru X8
;(adres jest względem wartości rejestru Program Counter)
adrp x8,__imp_ExitProcess
;rozkaz LDR lub ADD jest tutaj wymagany do utworzenia
;kompletnego adresu funkcji ExitProcess
ldr x8,[x8,__imp_ExitProcess]
;wywołanie funkcji ExitProcess, której adres jest w rejestrze X8
;adres powrotny jest zachowywany w rejestrze X30 (LR)
blr x8
ENDP
END
Proste operacje arytmetyczne
Proste operacje arytmetyczne można przeprowadzić za pomocą rozkazów:
ADD
(dodawanie),SUB
(odejmowanie),SUBS
(odejmowanie z ustawieniem flag),NEG
(zero odjąć wartość),MUL
(mnożenie),UDIV
(dzielenie bez znaku),SDIV
(dzielenie ze znakiem)- (...)
Przykładowy program prezentuje się następująco:
AREA .drectve, DRECTVE
AREA .rdata, DATA, READONLY
EXPORT Main
IMPORT |__imp_ExitProcess|
AREA .text, CODE, ARM64
Main PROC
stp fp,lr,[sp,#-0x10]!
mov fp,sp
mov x0,#0 ;rejestr X0 przyjmuje wartość zero
mov x7,#1 ;rejestr X7 przyjmuje wartość jeden
add x0,x7,#1 ;rejestr X0 przyjmuje wartość X7 dodać jeden, czyli dwa
mov x0,#0 ;rejestr X0 przyjmuje wartość zero
mov x7,#255 ;rejestr X7 przyjmuje wartość 255 (0xFF)
sub x0,x7,#1 ;rejestr X0 przyjmuje wartość X7 odjąć jeden, czyli 254
mov x0,#0 ;rejestr X0 przyjmuje wartość zero
mov x7,#128 ;rejestr X7 przyjmuje wartość 128
subs x0,x7,#1 ;rejestr X0 przyjmuje wartość X7 odjąć jeden, czyli 127
;(rozkaz SUBS ustawia flagi procesora)
;x0 = 0 - x7
mov x0,#0 ;rejestr X0 przyjmuje wartość zero
mov x7,#1 ;rejestr X7 przyjmuje wartość jeden
neg x0,x7 ;rejestr X0 przyjmuje wartość zero odjąć wartość rejestru X7
;x0 = x1 * x2
mov x0,#0 ;rejestr X0 przyjmuje wartość zero
mov x1,#4 ;rejestr X1 przyjmuje wartość cztery
mov x2,#4 ;rejestr X2 przyjmuje wartość cztery
mul x0,x1,x2 ;rejestr X0 przyjmuje wartość X1 pomnożone przez X2, czyli 4*4=16
;mnożenie z dodawaniem
;x0 = x1 * x2 + x3
;madd x0,x1,x2,x3
;x0 = x1 / x2 (bez znaku)
mov x0,#0 ;rejestr X0 przyjmuje wartość zero
mov x1,#10 ;rejestr X1 przyjmuje wartość dziesięć
mov x2,#2 ;rejestr X2 przyjmuje wartość dwa
udiv x0,x1,x2 ;rejestr X0 przyjmuje wartość X1 podzielone przez X2
;x0 = x1 / x2 (ze znakiem)
mov x0,#0 ;rejestr X0 przyjmuje wartość zero
mov x1,#32 ;rejestr X1 przyjmuje wartość trzydzieści dwa
mov x2,#2 ;rejestr X2 przyjmuje wartość dwa
sdiv x0,x1,x2 ;rejestr X0 przyjmuje wartość X1 podzielone przez X2
;wyjście z programu do systemu Windows
mov w0,#0
adrp x8,__imp_ExitProcess
ldr x8,[x8,__imp_ExitProcess]
blr x8
ENDP
END
Proste operacje logiczne
Proste operacje logiczne można przeprowadzić za pomocą rozkazów:
AND
(koniunkcja — Logical AND),ANDS
(koniunkcja z ustawieniem flag),ORR
(alternatywa — Logical OR),ORN
(alternatywa z zaprzeczonym trzecim operandem — Logical OR NOT),EON
(alternatywa wykluczająca z zaprzeczonym trzecim operandem — Logical Exclusive OR NOT),MVN
(negacja, zaprzeczenie — Logical NOT),EOR
(alternatywa wykluczająca — Logical XOR)- (...)
Przykładowy program prezentuje się następująco:
AREA .drectve, DRECTVE
AREA .rdata, DATA, READONLY
EXPORT Main
IMPORT |__imp_ExitProcess|
AREA .text, CODE, ARM64
Main PROC
stp fp,lr,[sp,#-0x10]!
mov fp,sp
;koniunkcja logiczna
mov w1,#0xFF0000FF ;rejestr W1 przyjmuje wartość 0xFF0000FF
and w0,w1,#0xFF00FF00 ;rejestr W0 przyjmuje wartość W1 and #0xFF00FF00
;koniunkcja logiczna
mov w1,#0xFF0000FF ;rejestr W1 przyjmuje wartość 0xFF0000FF
ands w0,w1,#0xFF00FF00 ;rejestr W0 przyjmuje wartość W1 and #0xFF00FF00
;(rozkaz ANDS ustawia flagi procesora)
;alternatywa logiczna
mov w1,#0xFF0000FF ;rejestr W1 przyjmuje wartość 0xFF0000FF
orr w0,w1,#0xFF00FF00 ;rejestr W0 przyjmuje wartość W1 or #0xFF00FF00
;alternatywa wykluczająca
mov w1,#0xFF0000FF ;rejestr W1 przyjmuje wartość 0xFF0000FF
eor w0,w1,#0xFF00FF00 ;rejestr W0 przyjmuje wartość W1 xor #0xFF00FF00
mov w0,#0
adrp x8,__imp_ExitProcess
ldr x8,[x8,__imp_ExitProcess]
blr x8
ENDP
END
Procedury (ang. procedures)
Tworzenie procedur ma głównie na celu podzielenie kodu źródłowego na mniejsze fragmenty,
które mogą być później wielokrotnie wywoływane, zamiast wklejania ich w miejsca gdzie są potrzebne.
Przykładowy program prezentuje wydzieloną procedurę ProcedureExample
, która wyświetla okno dialogowe za pomocą funkcji MessageBoxA
.
Wywołanie procedury za pomocą rozkazu BL
(ang. branch with link) zachowuje w rejestrze X30
(LR
)
adres powrotny, aby po wykonaniu fragmentu kodu zawartego w procedurze wrócić za miejsce rozgałęzienia.
AREA .drectve, DRECTVE
AREA .rdata, DATA, READONLY
szText DCB "Windows Arm64 Assembly Language", 0x00
EXPORT Main
IMPORT |__imp_ExitProcess|
IMPORT |__imp_MessageBoxA|
AREA .text, CODE, ARM64
Main PROC
stp fp,lr,[sp,#-0x10]!
mov fp,sp
;bezwarunkowe wywołanie procedury
bl ProcedureExample
mov w0,#0
adrp x8,__imp_ExitProcess
ldr x8,[x8,__imp_ExitProcess]
blr x8
ENDP
AREA .text, CODE, ARM64
ProcedureExample PROC
stp fp,lr,[sp,#-0x20]!
mov fp,sp
mov w3,#0
adrp x8,szText
add x2,x8, szText
adrp x8,szText
add x1,x8, szText
mov x0,#0
adrp x8,__imp_MessageBoxA
ldr x8,[x8,__imp_MessageBoxA]
blr x8
ldp fp,lr,[sp],#0x20
ret
ENDP
END
Podstawowe instrukcje (A64)
Instrukcje transferu danych
LDR (Wczytanie danych z pamięci do rejestru)
Dostęp do wartości w pamięci wykonywany jest na podstawie adresu liniowego (nazywanego też efektywnym). Najprostszy sposób adresowania to odczytanie wartości spod adresu zawartego w rejestrze.
Możliwe jest także uzyskanie dostępu do wartości w pamięci poprzez umieszczenie adresu bazowego w rejestrze i dodanie do tego adresu wartości przesunięcia (ang. offset). Przykładem zastosowania tego rodzaju adresowania może być uzyskiwanie dostępu do określonego pola struktury, gdzie adres bazowy struktury jest w rejestrze, a przesunięcia to adresy poszczególnych pól struktury względem adresu bazowego (początku).
Przykładowe adresowanie z preindeksowaniem można spotkać w prologu procedury, gdzie tworzona jest ramka stosu.
;(...)
stp fp,lr,[sp,#-0x40]!
mov fp,sp
;(...)
Za pomocą rozkazu STP
(ang. store pair) od wartości rejestru wskaźnika stosu SP
jest odejmowana wartość 0x40
(ponieważ jest to adresowanie z preindeksowaniem),
a na zarezerwowanym miejscu na stosie zachowywane są wartości rejestrów LR
(Link Register) oraz FP
(Frame Pointer).
Tego rodzaju operacja nazywana jest w prostych słowach odkładaniem wartości na stos programu. Dodatkowy rozkaz mov fp, sp
zachowuje w rejestrze FP
adres wskazujący na nową ramkę stosu.
W przypadku adresowania z postindeksowaniem wartość rejestru zawierającego adres bazowy jest modyfikowana po wykonaniu rozkazu odczytu lub zapisu. Z tego powodu tego rodzaju adresowania używa się np. przy zdejmowaniu wartości ze stosu — najpierw dane są odczytywane spod adresu w rejestrze, a dopiero później następuje modyfikacja aktualnej wartości adresu.
Za pomocą etykiet możliwe jest oznaczanie miejsc w kodzie do których można przekazywać sterowanie (przepływ wykonania programu). Nic jednak nie stoi na przeszkodzie, aby etykietą oznaczyć np. zdefiniowany ciąg bajtów i uzyskać dostęp do tego ładunku (ang. payload) używając nazwy etykiety czy też nazwy etykiety z przesunięciem.
Informacja
Adresowanie względem PC
pozwala utworzyć
kod niezależny od miejsca w pamięci (ang. position-independent code).
ADR (Adresowanie względem rejestru Program Counter)
Składnia:
ADR Xd, expression
Rozkaz ADR
pozwala uformować adres względem wartości rejestru PC
poprzez dodanie odpowiedniego przesunięcia w zakresie ±1 MB do aktualnej
wartości PC
i zapisanie uzyskanego adresu w 64-bitowym rejestrze ogólnego przeznaczenia.
ADRL (pseudoinstrukcja)
Składnia:
ADRL Xd, expression
ADRL Wd, expression
Pseudorozkaz ADRL
pozwala uformować adres względem wartości rejestru PC
podobnie jak instrukcja ADR
. Jednak pozwala sięgnąć dalej niż ±1MB,
ponieważ mnemonik ADRL
w kodzie maszynowym jest przeważnie tłumaczony na dwa rozkazy:
instrukcja ADR
, a po niej rozkaz ADD
. Dzięki temu zasięg formowanych adresów jest większy.
ADRP (Adresowanie względem rejestru PC do 4KB obszaru pamięci)
Składnia:
ADRP Xd, expression
Rozkaz ADRP
pozwala uformować adres względem wartości rejestru PC
poprzez dodanie odpowiedniego przesunięcia w zakresie ±4GB do aktualnej
wartości PC
i zapisanie uzyskanego adresu w 64-bitowym rejestrze ogólnego przeznaczenia.
MOV (Kopiowanie)
Składnia:
MOV Xd, Xm
MOV Wd, Wm
MOV Xd, #immediate
MOV Wd, #immediate
MOV Xd, SP
MOV Wd, WSP
MOV SP, Xm
MOV WSP, Wm
Rozkaz MOV
zawiera wiele wersji składniowych, a niektóre są nawet aliasami dla innych rozkazów.
Podstawowe możliwości tej instrukcji to:
- kopiowanie pomiędzy rejestrami ogólnego przeznaczenia (GPRs),
- kopiowanie pomiędzy rejestrem ogólnego przeznaczenia (GPR) a rejestrem wskaźnika stosu (
SP
), - kopiowanie wartości natychmiastowej (ang. immediate) do rejestru ogólnego przeznaczenia (GPR),
- (...)
LDP (Wczytanie danych z pamięci do pary rejestrów)
Składnia:
LDP Wa, Wb, [Xn, #offset]
LDP Wa, Wb, [SP, #offset]
LDP Xa, Xb, [Xn, #offset]
LDP Xa, Xb, [SP, #offset]
Składnia (adresowanie z preindeksowaniem):
LDP Wa, Wb, [Xn, #offset]!
LDP Wa, Wb, [SP, #offset]!
LDP Xa, Xb, [Xn, #offset]!
LDP Xa, Xb, [SP, #offset]!
Składnia (adresowanie z postindeksowaniem):
LDP Wa, Wb, [Xn], #offset
LDP Wa, Wb, [SP], #offset
LDP Xa, Xb, [Xn], #offset
LDP Xa, Xb, [SP], #offset
Rozkaz LDP
oblicza adres bazowy na podstawie wartości
rejestru Xn
/SP
oraz wartości przesunięcia (ang. offset), aby z pamięci o tym adresie załadować
dwa 32-bitowe słowa lub dwa 64-bitowe podwójne słowa do podanej pary rejestrów
Wa
/Wb
albo Xa
/Xb
.
Wartość przesunięcia (ang. offset) dla składni 32-bitowej to wielokrotność czwórki o maksymalnym zakresie od -256 do 252,
a dla składni 64-bitowej wielokrotność ósemki o maksymalnym zakresie od -512 do 504.
LDPSW (Wczytanie słów ze znakiem z pamięci do pary rejestrów)
Składnia:
LDPSW Xa, Xb, [Xn, #offset]
LDPSW Xa, Xb, [SP, #offset]
Składnia (adresowanie z preindeksowaniem):
LDPSW Xa, Xb, [Xn, #offset]!
LDPSW Xa, Xb, [SP, #offset]!
Składnia (adresowanie z postindeksowaniem):
LDPSW Xa, Xb, [Xn], #offset
LDPSW Xa, Xb, [SP], #offset
Rozkaz LDPSW
oblicza adres bazowy na podstawie wartości
rejestru Xn
/SP
oraz wartości przesunięcia (ang. offset), aby z pamięci o tym adresie załadować
dwa 32-bitowe słowa i rozszerzyć je z zachowaniem znaku (ang. sign extension),
a następnie wpisać do podanej pary rejestrów
Wa
/Wb
albo Xa
/Xb
.
Wartość przesunięcia (ang. offset) to wielokrotność czwórki o maksymalnym zakresie od -256 do 252.
LDRSB (Wczytanie bajta z pamięci do rejestru)
Składnia:
LDRSB Xt, [Xn, #offset_2]
LDRSB Wt, [Xn, #offset_2]
LDRSB Xt, [SP, #offset_2]
LDRSB Wt, [SP, #offset_2]
Składnia (adresowanie z preindeksowaniem):
LDRSB Xt, [Xn, #offset]!
LDRSB Wt, [Xn, #offset]!
LDRSB Xt, [SP, #offset]!
LDRSB Wt, [SP, #offset]!
Składnia (adresowanie z postindeksowaniem):
LDRSB Xt, [Xn], #offset
LDRSB Wt, [Xn], #offset
LDRSB Xt, [SP], #offset
LDRSB Wt, [SP], #offset
Rozkaz LDRSB
oblicza adres bazowy na podstawie wartości
rejestru Xn
/SP
oraz wartości przesunięcia (ang. offset), aby z pamięci o tym adresie załadować
bajt i rozszerzyć go z zachowaniem znaku (ang. sign extension),
a następnie wpisać do podanego rejestru
Wt
albo Xt
.
Wartość #offset
to przesunięcie o maksymalnym zakresie od -256 do 255.
Natomiast wartość #offset_2
to przesunięcie o maksymalnym zakresie od 0 do 4095.
LDRSH (Wczytanie połowy słowa z pamięci do rejestru)
Składnia:
LDRSH Xt, [Xn, #offset_2]
LDRSH Wt, [Xn, #offset_2]
LDRSH Xt, [SP, #offset_2]
LDRSH Wt, [SP, #offset_2]
Składnia (adresowanie z preindeksowaniem):
LDRSH Xt, [Xn, #offset]!
LDRSH Wt, [Xn, #offset]!
LDRSH Xt, [SP, #offset]!
LDRSH Wt, [SP, #offset]!
Składnia (adresowanie z postindeksowaniem):
LDRSH Xt, [Xn], #offset
LDRSH Wt, [Xn], #offset
LDRSH Xt, [SP], #offset
LDRSH Wt, [SP], #offset
Rozkaz LDRSH
oblicza adres bazowy na podstawie wartości
rejestru Xn
/SP
oraz wartości przesunięcia (ang. offset), aby z pamięci o tym adresie załadować
pół słowa maszynowego i rozszerzyć je z zachowaniem znaku (ang. sign extension),
a następnie wpisać do podanego rejestru
Wt
albo Xt
.
Wartość #offset
to przesunięcie o maksymalnym zakresie od -256 do 255.
Natomiast wartość #offset_2
to przesunięcie, które jest wielokrotnością dwójki o maksymalnym zakresie od 0 do 8190.
LDRSW (Wczytanie słowa ze znakiem z pamięci do rejestru)
Składnia:
LDRSW Xt, [Xn, #offset_2]
LDRSW Xt, [SP, #offset_2]
Składnia (adresowanie z preindeksowaniem):
LDRSW Xt, [Xn, #offset]!
LDRSW Xt, [SP, #offset]!
Składnia (adresowanie z postindeksowaniem):
LDRSW Xt, [Xn], #offset
LDRSW Xt, [SP], #offset
Rozkaz LDRSW
oblicza adres bazowy na podstawie wartości
rejestru Xn
/SP
oraz wartości przesunięcia (ang. offset), aby z pamięci o tym adresie załadować
słowo maszynowe i rozszerzyć je z zachowaniem znaku (ang. sign extension),
a następnie wpisać do podanego rejestru
Wt
albo Xt
.
Wartość #offset
to przesunięcie o maksymalnym zakresie od -256 do 255.
Natomiast wartość #offset_2
to przesunięcie, które jest wielokrotnością czwórki o maksymalnym zakresie od 0 do 16380.
STP (Zapisanie wartości pary rejestrów do pamięci)
Składnia:
STP Wa, Wb, [Xn, #offset]
STP Wa, Wb, [SP, #offset]
STP Xa, Xb, [Xn, #offset]
STP Xa, Xb, [SP, #offset]
Składnia (adresowanie z preindeksowaniem):
STP Wa, Wb, [Xn, #offset]!
STP Wa, Wb, [SP, #offset]!
STP Xa, Xb, [Xn, #offset]!
STP Xa, Xb, [SP, #offset]!
Składnia (adresowanie z postindeksowaniem):
STP Wa, Wb, [Xn], #offset
STP Wa, Wb, [SP], #offset
STP Xa, Xb, [Xn], #offset
STP Xa, Xb, [SP], #offset
Rozkaz STP
oblicza adres bazowy na podstawie wartości
rejestru Xn
/SP
oraz wartości przesunięcia (ang. offset), aby do pamięci o tym adresie zapisać
dwa 32-bitowe słowa lub dwa 64-bitowe podwójne podanej pary rejestrów
Wa
/Wb
albo Xa
/Xb
.
Wartość przesunięcia (ang. offset) dla składni 32-bitowej to wielokrotność czwórki o maksymalnym zakresie od -256 do 252,
a dla składni 64-bitowej wielokrotność ósemki o maksymalnym zakresie od -512 do 504.
STR (Zapisanie wartości rejestru do pamięci)
Składnia:
STR Xt, [Xn, #offset_2]
STR Xt, [SP, #offset_2]
STR Wt, [Xn, #offset_2]
STR Wt, [SP, #offset_2]
Składnia (adresowanie z preindeksowaniem):
STR Xt, [Xn, #offset]!
STR Xt, [SP, #offset]!
STR Wt, [Xn, #offset]!
STR Wt, [SP, #offset]!
Składnia (adresowanie z postindeksowaniem):
STR Xt, [Xn], #offset
STR Xt, [SP], #offset
STR Wt, [Xn], #offset
STR Wt, [SP], #offset
Rozkaz STR
oblicza adres bazowy na podstawie wartości
rejestru Xn
/SP
oraz wartości przesunięcia (ang. offset), aby do pamięci o tym adresie zapisać
słowo maszynowe lub podwójne słowo.
Wartość #offset
to przesunięcie o maksymalnym zakresie od -256 do 255.
Natomiast wartość #offset_2
to przesunięcie, które dla składni 32-bitowej to
wielokrotność czwórki o maksymalnym zakresie od 0 do 16380,
a dla składni 64-bitowej wielokrotność ósemki o maksymalnym zakresie od 0 do 32760.
STRB (Zapisanie najmłodszego bajta z rejestru do pamięci)
Składnia:
STRB Wt, [Xn, #offset_2]
STRB Wt, [SP, #offset_2]
Składnia (adresowanie z preindeksowaniem):
STRB Wt, [Xn, #offset]!
STRB Wt, [SP, #offset]!
Składnia (adresowanie z postindeksowaniem):
STRB Wt, [Xn], #offset
STRB Wt, [SP], #offset
Rozkaz STRB
oblicza adres bazowy na podstawie wartości
rejestru Xn
/SP
oraz wartości przesunięcia (ang. offset), aby do pamięci o tym adresie zapisać
najmłodszy bajt rejestru Wt
.
Wartość #offset
to przesunięcie o maksymalnym zakresie od -256 do 255.
Natomiast wartość #offset_2
to przesunięcie o maksymalnym zakresie od 0 do 4095.
STRH (Zapisanie połowy słowa maszynowego z rejestru do pamięci)
Składnia:
STRH Wt, [Xn, #offset_2]
STRH Wt, [SP, #offset_2]
Składnia (adresowanie z preindeksowaniem):
STRH Wt, [Xn, #offset]!
STRH Wt, [SP, #offset]!
Składnia (adresowanie z postindeksowaniem):
STRH Wt, [Xn], #offset
STRH Wt, [SP], #offset
Rozkaz STRH
oblicza adres bazowy na podstawie wartości
rejestru Xn
/SP
oraz wartości przesunięcia (ang. offset), aby do pamięci o tym adresie zapisać
młodszą połowę słowa maszynowego rejestru Wt
.
Wartość #offset
to przesunięcie o maksymalnym zakresie od -256 do 255.
Natomiast wartość #offset_2
to przesunięcie, które jest wielokrotnością dwójki o maksymalnym zakresie od 0 do 8190.
Instrukcje arytmetyczne
ADC (Dodawanie z przeniesieniem)
Składnia:
ADC Xd, Xa, Xb ;64-bit
ADC Wd, Wa, Wb ;32-bit
Rozkaz ADC
dodaje wartości rejestrów Xa
(lub Wa
) i Xb
(lub Wb
)
oraz wartość flagi przeniesienia (C
) i zapisuje wynik w rejestrze docelowym Xd
(lub Wd
).
ADCS (Dodawanie z przeniesieniem, ustawia flagi)
Składnia:
ADCS Xd, Xa, Xb ;64-bit
ADCS Wd, Wa, Wb ;32-bit
Rozkaz ADCS
dodaje wartości rejestrów Xa
(lub Wa
) i Xb
(lub Wb
)
oraz wartość flagi przeniesienia (C
) i zapisuje wynik w rejestrze docelowym Xd
(lub Wd
).
Ustawia flagi procesora zgodnie z rezultatem operacji.
ADD (Dodawanie)
Składnia:
ADD Xd, Xa, Xb
ADD Wd, Wa, Wb
ADD Xd, Xa, #immediate
ADD Wd, Wa, #immediate
Rozkaz ADD
dodaje wartości rejestrów Xa
(lub Wa
) i Xb
(lub Wb
)
i zapisuje wynik w rejestrze docelowym Xd
(lub Wd
).
Inna wersja składni umożliwia dodanie wartości rejestru Xa
(lub Wa
) oraz wartości natychmiastowej (ang. immediate)
i zapisanie wyniku w rejestrze docelowym Xd
(lub Wd
).
ADDS (Dodawanie, ustawia flagi)
Składnia:
ADDS Xd, Xa, Xb
ADDS Wd, Wa, Wb
ADDS Xd, Xa, #immediate
ADDS Wd, Wa, #immediate
Rozkaz ADDS
dodaje wartości rejestrów Xa
(lub Wa
) i Xb
(lub Wb
)
i zapisuje wynik w rejestrze docelowym Xd
(lub Wd
).
Inna wersja składni umożliwia dodanie wartości rejestru Xa
(lub Wa
) oraz wartości natychmiastowej (ang. immediate)
i zapisanie wyniku w rejestrze docelowym Xd
(lub Wd
).
Ustawia flagi procesora zgodnie z rezultatem operacji.
CLS (Zliczenie wiodących bitów znaku)
Składnia:
CLS Xd, Xa ;64-bit
CLS Wd, Wa ;32-bit
Rozkaz CLS
zlicza wiodące bity znaku w rejestrze Xa
(lub Wa
)
i zapisuje rezultat operacji do rejestru docelowego Xd
(lub Wd
).
CLZ (Zliczenie wiodących bitów zerowych)
Składnia:
CLZ Xd, Xa ;64-bit
CLZ Wd, Wa ;32-bit
Rozkaz CLZ
zlicza wiodące bity zerowe w rejestrze Xa
(lub Wa
)
i zapisuje rezultat operacji do rejestru docelowego Xd
(lub Wd
).
MADD (Mnożenie z dodawaniem)
Składnia:
MADD Xd, Xa, Xb, Xc ;64-bit
MADD Wd, Wa, Wb, Wc ;32-bit
Rozkaz MADD
mnoży wartość rejestru Xa
przez Xb
i dodaje do rezultatu wartość rejestru Xc
zapisując wynik całej operacji w rejestrze docelowym Xd
.
Inna wersja składni (32-bitowa) pozwala użyć rejestrów Wn
.
Pseudokod: Xd = Xa * Xb + Xc
MNEG (Mnożenie z negacją)
Składnia:
MNEG Xd, Xa, Xb ;64-bit
MNEG Wd, Wa, Wb ;32-bit
Rozkaz MNEG
mnoży wartość rejestru Xa
przez Xb
, neguje rezultat
i zapisuje wynik całej operacji w rejestrze docelowym Xd
.
Inna wersja składni (32-bitowa) pozwala użyć rejestrów Wn
.
Pseudokod: Xd = -(Xa * Xb)
MSUB (Mnożenie z odejmowaniem)
Składnia:
MSUB Xd, Xa, Xb, Xc ;64-bit
MSUB Wd, Wa, Wb, Wc ;32-bit
Rozkaz MSUB
mnoży wartość rejestru Xa
przez Xb
i odejmuje rezultat od wartości rejestru Xc
.
Inna wersja składni (32-bitowa) pozwala użyć rejestrów Wn
.
Pseudokod: Xd = Xc - (Xa * Xb)
MUL (Mnożenie)
Składnia:
MUL Xd, Xa, Xb ;64-bit
MUL Wd, Wa, Wb ;32-bit
Rozkaz MUL
mnoży wartość rejestru Xa
przez Xb
i zapisuje wynik w rejestrze docelowym Xd
Inna wersja składni (32-bitowa) pozwala użyć rejestrów Wn
.
Pseudokod: Xd = Xa * Xb
SBC (Odejmowanie z przeniesieniem)
Składnia:
SBC Xd, Xa, Xb ;64-bit
SBC Wd, Wa, Wb ;32-bit
Rozkaz SBC
odejmuje wartość rejestru Xb
(lub Wb
) od wartości rejestru Xa
(lub Wa
)
oraz wartość zanegowanej flagi przeniesienia (C
) i zapisuje wynik w rejestrze docelowym Xd
(lub Wd
).
Pseudokod: Xd = Xa - Xb - 1 + C
SBCS (Odejmowanie z przeniesieniem, ustawia flagi)
Składnia:
SBCS Xd, Xa, Xb ;64-bit
SBCS Wd, Wa, Wb ;32-bit
Rozkaz SBCS
odejmuje wartość rejestru Xb
(lub Wb
) od wartości rejestru Xa
(lub Wa
)
oraz wartość zanegowanej flagi przeniesienia (C
) i zapisuje wynik w rejestrze docelowym Xd
(lub Wd
).
Ustawia flagi procesora zgodnie z rezultatem operacji.
Pseudokod: Xd = Xa - Xb - 1 + C
SDIV (Dzielenie ze znakiem)
Składnia:
SDIV Xd, Xa, Xb ;64-bit
SDIV Wd, Wa, Wb ;32-bit
Rozkaz SDIV
dzieli wartość całkowitą z rejestru Xa
(lub Wa
) przez Xb
(lub Wb
)
zapisując wynik w rejestrze docelowym Xd
(lub Wd
). Instrukcja ta nie ma wpływu na flagi warunkowe procesora.
Pseudokod: Xd = Xa / Xb
SUB (Odejmowanie)
Składnia:
SUB Xd, Xa, Xb
SUB Wd, Wa, Wb
SUB Xd, Xa, #immediate
SUB Wd, Wa, #immediate
Rozkaz SUB
odejmuje wartość rejestru Xa
(lub Wa
) od Xb
(lub Wb
)
i zapisuje wynik w rejestrze docelowym Xd
(lub Wd
).
Inna wersja składni umożliwia odjęcie wartości natychmiastowej (ang. immediate) od wartości rejestru Xa
(lub Wa
)
i zapisanie wyniku w rejestrze docelowym Xd
(lub Wd
).
Pseudokod:
Xd = Xa - Xb
Xd = Xa - immediate
SUBS (Odejmowanie, ustawia flagi)
Składnia:
SUBS Xd, Xa, Xb
SUBS Wd, Wa, Wb
SUBS Xd, Xa, #immediate
SUBS Wd, Wa, #immediate
Rozkaz SUBS
odejmuje wartość rejestru Xa
(lub Wa
) od Xb
(lub Wb
)
i zapisuje wynik w rejestrze docelowym Xd
(lub Wd
).
Inna wersja składni umożliwia odjęcie wartości natychmiastowej (ang. immediate) od wartości rejestru Xa
(lub Wa
)
i zapisanie wyniku w rejestrze docelowym Xd
(lub Wd
).
Ustawia flagi procesora zgodnie z rezultatem operacji.
Pseudokod:
Xd = Xa - Xb
Xd = Xa - immediate
UDIV (Dzielenie bez znaku)
Składnia:
UDIV Xd, Xa, Xb ;64-bit
UDIV Wd, Wa, Wb ;32-bit
Rozkaz UDIV
dzieli wartość całkowitą z rejestru Xa
(lub Wa
) przez Xb
(lub Wb
)
zapisując wynik w rejestrze docelowym Xd
(lub Wd
). Instrukcja ta nie ma wpływu na flagi warunkowe procesora.
Pseudokod: Xd = Xa / Xb
Instrukcje logiczne
AND (Koniunkcja logiczna)
Składnia:
AND Xd, Xa, Xb
AND Wd, Wa, Wb
AND Xd, Xa, #immediate
AND Wd, Wa, #immediate
Rozkaz AND
wykonuje koniunkcję logiczną wartości z rejestru Xa
(lub Wa
) i Xb
(lub Wb
)
zapisując wynik w rejestrze docelowym Xd
(lub Wd
).
Inna wersja składni pozwala na wykonanie koniunkcji logicznej wartości z rejestru Xa
(lub Wa
) oraz wartości natychmiastowej (ang. immediate).
Pseudokod:
Xd = Xa AND Xb
Xd = Xa AND immediate
ANDS (Koniunkcja logiczna, ustawia flagi)
Składnia:
ANDS Xd, Xa, Xb
ANDS Wd, Wa, Wb
ANDS Xd, Xa, #immediate
ANDS Wd, Wa, #immediate
Rozkaz ANDS
wykonuje koniunkcję logiczną wartości z rejestru Xa
(lub Wa
) i Xb
(lub Wb
)
zapisując wynik w rejestrze docelowym Xd
(lub Wd
).
Inna wersja składni pozwala na wykonanie koniunkcji logicznej wartości z rejestru Xa
(lub Wa
) oraz wartości natychmiastowej (ang. immediate).
Ustawia flagi procesora zgodnie z rezultatem operacji.
Pseudokod:
Xd = Xa AND Xb
Xd = Xa AND immediate
ASR (Arytmetyczne przesunięcie w prawo)
Składnia:
ASR Xd, Xa, Xb
ASR Wd, Wa, Wb
ASR Xd, Xa, #immediate
ASR Wd, Wa, #immediate
Rozkaz ASR
wykonuje arytmetyczne przesunięcie w prawo wartości z rejestru Xa
(lub Wa
)
o liczbę bitów zakodowaną na sześciu najmłodszych bitach rejestru Xb
o zakresie od 0 do 63
(lub na pięciu najmłodszych bitach rejestru Wb
o zakresie od 0 do 31).
Inna wersja składni pozwala wykonać arytmetyczne przesunięcie w prawo o liczbę bitów podaną jako wartość natychmiastowa (ang. immediate)
o zakresie od 0 do 63 (składnia 64-bitowa) lub od 0 do 31 (składnia 32-bitowa).
Informacja: Przesunięcie arytmetyczne w prawo zachowuje bit znaku.
BIC (Koniunkcja logiczna z zanegowanym operandem)
Składnia:
BIC Xd, Xa, Xb
BIC Wd, Wa, Wb
Rozkaz BIC
wykonuje koniunkcję logiczną wartości z rejestru Xa
(lub Wa
)
i zanegowanej wartości z rejestru Xb
(lub Wb
)
zapisując wynik w rejestrze docelowym Xd
(lub Wd
).
Pseudokod:
Xd = Xa AND NOT Xb
EON (Alternatywa wykluczająca z zanegowanym operandem)
Składnia:
EON Xd, Xa, Xb
EON Wd, Wa, Wb
Rozkaz EON
wykonuje alternatywę wykluczającą wartości z rejestru Xa
(lub Wa
)
i zanegowanej wartości z rejestru Xb
(lub Wb
)
zapisując wynik w rejestrze docelowym Xd
(lub Wd
).
Pseudokod:
Xd = Xa EOR NOT Xb
EOR (Alternatywa wykluczająca)
Składnia:
EOR Xd, Xa, Xb
EOR Wd, Wa, Wb
EOR Xd, SP, #immediate
EOR Wd, WSP, #immediate
EOR Xd, Xa, #immediate
EOR Wd, Wa, #immediate
Rozkaz EOR
wykonuje alternatywę wykluczającą wartości z rejestru Xa
(lub Wa
)
i wartości z rejestru Xb
(lub Wb
)
zapisując wynik w rejestrze docelowym Xd
(lub Wd
).
Inna wersja składni pozwala na wykonanie tej samej operacji z użyciem wartości natychmiastowej (ang. immediate).
Pseudokod:
Xd = Xa EOR Xb
Xd = Xa EOR immediate
LSL (Logiczne przesunięcie w lewo)
Składnia:
LSL Xd, Xa, Xb
LSL Wd, Wa, Wb
LSL Xd, Xa, #immediate
LSL Wd, Wa, #immediate
Rozkaz LSL
wykonuje logiczne przesunięcie w lewo wartości z rejestru Xa
(lub Wa
)
o liczbę bitów zakodowaną na sześciu najmłodszych bitach rejestru Xb
o zakresie od 0 do 63
(lub na pięciu najmłodszych bitach rejestru Wb
o zakresie od 0 do 31).
Inna wersja składni pozwala wykonać logiczne przesunięcie w lewo o liczbę bitów podaną jako wartość natychmiastowa (ang. immediate)
o zakresie od 0 do 63 (składnia 64-bitowa) lub od 0 do 31 (składnia 32-bitowa).
Informacja: Na miejsce przesuniętych w lewo bitów wpisywane są zera.
LSR (Logiczne przesunięcie w prawo)
Składnia:
LSR Xd, Xa, Xb
LSR Wd, Wa, Wb
LSR Xd, Xa, #immediate
LSR Wd, Wa, #immediate
Rozkaz LSR
wykonuje logiczne przesunięcie w prawo wartości z rejestru Xa
(lub Wa
)
o liczbę bitów zakodowaną na sześciu najmłodszych bitach rejestru Xb
o zakresie od 0 do 63
(lub na pięciu najmłodszych bitach rejestru Wb
o zakresie od 0 do 31).
Inna wersja składni pozwala wykonać logiczne przesunięcie w prawo o liczbę bitów podaną jako wartość natychmiastowa (ang. immediate)
o zakresie od 0 do 63 (składnia 64-bitowa) lub od 0 do 31 (składnia 32-bitowa).
MVN (Zaprzeczenie logiczne)
Składnia:
MVN Xd, Xa
MVN Wd, Wa
Rozkaz MVN
wykonuje logiczne zaprzeczenie wartości z rejestru Xa
(lub Wa
)
zapisując rezultat do rejestru docelowego Xd
(lub Wd
).
Pseudokod:
Xd = NOT Xa
NEG (Negacja z uzupełnieniem do dwóch)
Składnia:
NEG Xd, Xa
NEG Wd, Wa
Rozkaz NEG
odejmuje wartość z rejestru Xa
(lub Wa
)
od zera zapisując rezultat do rejestru docelowego Xd
(lub Wd
).
Pseudokod:
Xd = 0 - Xa
NEGS (Negacja z uzupełnieniem do dwóch, ustawia flagi)
Składnia:
NEGS Xd, Xa
NEGS Wd, Wa
Rozkaz NEGS
odejmuje wartość z rejestru Xa
(lub Wa
)
od zera zapisując rezultat do rejestru docelowego Xd
(lub Wd
).
Ustawia flagi procesora zgodnie z rezultatem operacji.
Pseudokod:
Xd = 0 - Xa
ORN (Alternatywa z zanegowanym operandem)
Składnia:
ORN Xd, Xa, Xb
ORN Wd, Wa, Wb
Rozkaz ORN
wykonuje alternatywę wartości z rejestru Xa
(lub Wa
)
i zanegowanej wartości z rejestru Xb
(lub Wb
)
zapisując wynik w rejestrze docelowym Xd
(lub Wd
).
Pseudokod:
Xd = Xa OR NOT Xb
ORR (Alternatywa logiczna)
Składnia:
ORR Xd, Xa, Xb
ORR Wd, Wa, Wb
ORR Xd, SP, #immediate
ORR Wd, WSP, #immediate
ORR Xd, Xa, #immediate
ORR Wd, Wa, #immediate
Rozkaz ORR
wykonuje alternatywę logiczną wartości z rejestru Xa
(lub Wa
)
i wartości z rejestru Xb
(lub Wb
)
zapisując wynik w rejestrze docelowym Xd
(lub Wd
).
Inna wersja składni pozwala na wykonanie tej samej operacji z użyciem wartości natychmiastowej (ang. immediate).
Pseudokod:
Xd = Xa OR Xb
Xd = Xa OR immediate
RBIT (Odwrócenie kolejności bitów w rejestrze)
Składnia:
RBIT Xd, Xa
RBIT Wd, Wa
Rozkaz RBIT
odwraca kolejność bitów w rejestrze Xa
(lub Wa
)
i zapisuje wynik w rejestrze docelowym Xd
(lub Wd
).
ROR (Obrót bitów w prawo)
Składnia:
ROR Xd, Xa, Xb
ROR Wd, Wa, Wb
ROR Xd, Xa, #immediate
ROR Wd, Wa, #immediate
Rozkaz ROR
wykonuje obrót w prawo bitów z rejestru Xa
(lub Wa
)
o liczbę bitów zakodowaną na sześciu najmłodszych bitach rejestru Xb
o zakresie od 0 do 63
(lub na pięciu najmłodszych bitach rejestru Wb
o zakresie od 0 do 31).
Inna wersja składni pozwala wykonać logiczne przesunięcie w lewo o liczbę bitów podaną jako wartość natychmiastowa (ang. immediate)
o zakresie od 0 do 63 (składnia 64-bitowa) lub od 0 do 31 (składnia 32-bitowa).
Informacja: Bity wyrzucone z prawej strony podczas obrotu wchodzą z lewej strony z powrotem do rejestru.
Rozgałęzienia (ang. branch)
B (Rozgałęzienie)
Składnia:
B label
Rozkaz B
(ang. branch) wykonuje przejście do określonego miejsca w kodzie
oznaczonego etykietą.
Możliwe jest przejście wstecz lub do przodu o zakresie ±128 MB
licząc od adresu bieżącej instrukcji.
BL (Rozgałęzienie z adresem powrotnym)
Składnia:
BL label
Rozkaz BL
(ang. branch with link) wykonuje przejście do określonego miejsca w kodzie
oznaczonego etykietą
i ustawia wartość rejestru X30
(LR
)
na PC + 4
.
Możliwe jest przejście wstecz lub do przodu o zakresie ±128 MB
licząc od adresu bieżącej instrukcji.
BLR (Rozgałęzienie z użyciem rejestru z adresem powrotnym)
Składnia:
BLR Xn
Rozkaz BLR
(ang. branch with link to register) wykonuje przejście do określonego miejsca w kodzie,
którego adres jest w rejestrze ogólnego przeznaczenia Xn
i ustawia wartość rejestru X30
(LR
)
na PC + 4
.
Możliwe jest przejście wstecz lub do przodu o zakresie ±128 MB
licząc od adresu bieżącej instrukcji.
BR (Rozgałęzienie z użyciem rejestru)
Składnia:
BR Xn
Rozkaz BR
(ang. branch to register) wykonuje przejście do określonego miejsca w kodzie,
którego adres jest w rejestrze ogólnego przeznaczenia Xn
.
Możliwe jest przejście wstecz lub do przodu o zakresie ±128 MB
licząc od adresu bieżącej instrukcji.
BEQ (Rozgałęzienie warunkowe, jeśli równe)
Składnia:
BEQ label
Rozkaz BEQ
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy ustawiona jest flaga zerowa (Z
).
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BNE (Rozgałęzienie warunkowe, jeśli różne)
Składnia:
BNE label
Rozkaz BNE
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy flaga zerowa (Z
) nie jest ustawiona.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BCS/BHS (Rozgałęzienie warunkowe, jeśli przeniesienie)
Składnia:
BCS label
BHS label
Rozkazy BCS
i BHS
wykonują warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy ustawiona jest flaga przeniesienia (C
),
co można rozumieć jako większe bądź równe bez znaku.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BCC/BLO (Rozgałęzienie warunkowe, jeśli brak przeniesienia)
Składnia:
BCC label
BLO label
Rozkazy BCC
i BLO
wykonują warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy flaga przeniesienia (C
) nie jest ustawiona,
co można rozumieć jako mniejsze bez znaku.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BMI (Rozgałęzienie warunkowe, jeśli ujemny)
Składnia:
BMI label
Rozkaz BMI
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy ustawiona jest flaga ujemna (N
).
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BPL (Rozgałęzienie warunkowe, jeśli dodatni lub zero)
Składnia:
BPL label
Rozkaz BPL
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy flaga ujemna (N
) nie jest ustawiona.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BVS (Rozgałęzienie warunkowe, jeśli przepełnienie)
Składnia:
BVS label
Rozkaz BVS
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy ustawiona jest flaga przepełnienia (V
).
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BVC (Rozgałęzienie warunkowe, jeśli brak przepełnienia)
Składnia:
BVC label
Rozkaz BVC
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy flaga przepełnienia (V
) nie jest ustawiona.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BHI (Rozgałęzienie warunkowe, jeśli większe bez znaku)
Składnia:
BHI label
Rozkaz BHI
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy flaga przeniesienia (C
)
jest ustawiona, a flaga zerowa (Z
) nie jest ustawiona.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BLS (Rozgałęzienie warunkowe, jeśli mniejsze bądź równe bez znaku)
Składnia:
BLS label
Rozkaz BLS
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy flaga przeniesienia (C
)
nie jest ustawiona, a flaga zerowa (Z
) jest ustawiona.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BGE (Rozgałęzienie warunkowe, jeśli większe bądź równe ze znakiem)
Składnia:
BGE label
Rozkaz BGE
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy flagi N
i V
mają taką samą wartość.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BLT (Rozgałęzienie warunkowe, jeśli mniejsze ze znakiem)
Składnia:
BLT label
Rozkaz BLT
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy flagi N
i V
mają różne od siebie wartości.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BGT (Rozgałęzienie warunkowe, jeśli większe ze znakiem)
Składnia:
BGT label
Rozkaz BGT
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy flagi N
i V
mają taką samą wartość, a flaga Z
nie jest ustawiona.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BLE (Rozgałęzienie warunkowe, jeśli mniejsze ze znakiem)
Składnia:
BLE label
Rozkaz BLE
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą, gdy flagi N
i V
mają różne od siebie wartości oraz flaga Z
jest ustawiona.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
BAL (Rozgałęzienie warunkowe, Zawsze)
Składnia:
BAL label
Rozkaz BAL
wykonuje warunkowe przejście do określonego miejsca w kodzie
oznaczonego etykietą. Przyrostek (kod warunkowy AL
, ang. always) jest przeważnie pomijany
i stosuje się instrukcję rozgałęzienia bezwarunkowego B
.
Możliwe jest przejście wstecz lub do przodu o zakresie ±1 MB
licząc od adresu bieżącej instrukcji.
RET (Powrót z rozgałęzienia)
Składnia:
RET Xn
Rozkaz RET
wykonuje powrót do określonego miejsca w kodzie,
którego adres jest w rejestrze ogólnego przeznaczenia Xn
.
Domyślnie adres instrukcji do której ma nastąpić powrót jest pobierany z rejestru X30
(LR
),
wtedy rozkaz jest wywoływany bez operandu.
Inne (ang. misc)
REV (Odwrócenie kolejności bajtów w rejestrze)
Składnia:
REV64 Xd, Xa
REV Xd, Xa
REV Wd, Wa
Rozkaz REV
odwraca kolejność bajtów w rejestrze Xa
(lub Wa
)
i zapisuje wynik w rejestrze docelowym Xd
(lub Wd
).
CMP (Porównanie)
Składnia:
CMP Xa, Xb
CMP Wa, Wb
CMP SP, Xb
CMP WSP, Wb
CMP SP, #immediate
CMP WSP, #immediate
CMP Xa, #immediate
CMP Wa, #immediate
Rozkaz CMP
wykonuje porównanie wartości dwóch operandów poprzez wykonanie odejmowania (SUB
)
z ustawieniem flag, ale bez zapisywania wyniku. Po tej instrukcji przeważnie występują rozkazy warunkowe.
TST (Test)
Składnia:
TST Xa, Xb
TST Wa, Wb
TST Xa, #immediate
TST Wa, #immediate
Rozkaz TST
wykonuje porównanie wartości dwóch operandów poprzez wykonanie koniunkcji logicznej (AND
)
z ustawieniem flag, ale bez zapisywania wyniku. Po tej instrukcji przeważnie występują rozkazy warunkowe.
Wskazówka: TST Xn, Xn
pozwala łatwo sprawdzić czy wartość rejestru to zero.
Wykaz literatury
- [1] https://developer.arm.com/documentation/ [dostęp: 2024-02-21]
- [2] https://learn.microsoft.com/en-us/cpp/assembler/arm/arm-assembler-reference [dostęp: 2024-02-21]
- [3] Arm ® Architecture Reference Manual for A-profile architecture by Arm Limited