ethical.blue Magazine

// Cybersecurity clarified.

Asembler Arm64 dla Windows. Podstawowa wiedza w kapsułce

...
Assembly Language // // Dawid Farbaniec
Ostatnia modyfikacja:

Spis treści

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

...
Systemy operacyjne Windows dla procesorów Arm dostępne na platformie Azure

Platformę sprzętową na której zainstalowano system Windows można odczytać np. za pomocą PowerShell.

Code:
Get-WmiObject -Class Win32_ComputerSystem | Select-Object -Property SystemType
...
Odczytanie platformy sprzętowej oraz wersji systemu Windows za pomocą PowerShell

Informacje o architekturze procesora można też znaleźć w oknie informacji o systemie (System > About).

...
Połączenie przez zdalny pulpit z maszyną wirtualną na platformie Azure

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:

Dlatego często można spotkać zapis np. Armv9-A, który oznacza architekturę Arm dziewiątej generacji i profil Application.

Typy danych

Stos programu

...
Kierunek rośnięcia stosu programu (AArch64)

Format przykładowego rozkazu

...
Przykładowy rozkaz w języku Asembler dla Arm64 (AArch64)

Rejestry R0...R30

Rejestry od R0 do R30 są udostępniane w postaci:

...
Rejestry ogólnego przeznaczenia (AArch64)

Rejestry V0...V31 oraz FPSR i FPCR

Rejestry od V0 do V31 są udostępniane w postaci:

...
Rejestry przeznaczone do operacji zmiennoprzecinkowych i SIMD (AArch64)

Rejestry Z0...Z31

Rejestry od Z0 do Z31 są używane w rozkazach SVE.

...
Rejestry przeznaczone dla rozkazów Scalable Vector Extension (AArch64)

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 PC (AArch64)

Rejestr Stack Pointer

Rejestr wskaźnika stosu. Nie jest to rejestr ogólnego przeznaczenia. Rejestr SP jest rejestrem specjalnym.

...
Rejestr SP (AArch64)

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

...
Rejestr z flagami NZCV (AArch64)

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:

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

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

Code:
;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.

Code:
;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.

Code:
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ą.

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

Code:
  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
Download:

Proste operacje arytmetyczne

Proste operacje arytmetyczne można przeprowadzić za pomocą rozkazów:

Przykładowy program prezentuje się następująco:

Code:
  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
Download:

Proste operacje logiczne

Proste operacje logiczne można przeprowadzić za pomocą rozkazów:

Przykładowy program prezentuje się następująco:

Code:
  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
Download:

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.

Code:
  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
Download:

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.

...
Adresowanie pośrednie przez rejestr (AArch64)

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

...
Adresowanie pośrednie przez rejestr z przesunięciem (AArch64)

Przykładowe adresowanie z preindeksowaniem można spotkać w prologu procedury, gdzie tworzona jest ramka stosu.

Code:
;(...)
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.

...
Adresowanie pośrednie przez rejestr z preindeksowaniem (AArch64)

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.

...
Adresowanie pośrednie przez rejestr z postindeksowaniem (AArch64)

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.

...
Adresowanie względem rejestru Program Counter (AArch64)
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:

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. [1] https://developer.arm.com/documentation/ [dostęp: 2024-02-21]
  2. [2] https://learn.microsoft.com/en-us/cpp/assembler/arm/arm-assembler-reference [dostęp: 2024-02-21]
  3. [3] Arm ® Architecture Reference Manual for A-profile architecture by Arm Limited