David Schirrmeister 5d0ad57e2e update
2024-06-09 21:47:55 +02:00

12 KiB

ARM Befehle

ARM 7

  • Architektur: ARM v4T, Prozessor ARM7 TDMI
  • 1994 rausgekommen
  • 12-70 MHz, 0,889 DMIPS/MHz
  • RISC, Load-Store-Architektur
  • 3-stufige Pipeline
  • Instruction Set
  • Little Endian als Standard

ARM-Datenpfad

image_302.png

ARM7-ALU

image_303.png

ARM7-Pipeline für ALU-Befehle

image_304.png

  • Latenz
    • 3 Zyklen
  • Durchsatz
    • 1 Befehl je Zyklus

Multi-cycle Execution

  • Execute benötigt einen Takt für simple Instruktionen
  • Bei Speicherzugriff mind. 2 Takte
    • Adress Berechnung
    • Speicherzugriff
  • image_305.png

Load/Store Befehle Hazard in Von-Neumann

image_306.png

image_307.png

ARM Registerstruktur

image_309.png

Statusflags

  • N (Negative)
    • Das Ergebnis der ALU ist negativ (Bit 31=1)
  • Z (Zero)
    • Das Ergebnis der ALU ist Null (Bit 0..31 = 0)
  • C (Carry)
    • Bei arithmetischer Operation wird C auf Carry-Out der ALU gesetzt
    • Sonst auf Carry-Out des Shifters bzw. ohne Shift Operation bleibt C erhalten
  • V (Overflow)
    • Wenn Zahlensystem geändert wird
    • Wenn mit unsigned gerechnet wird ist V ohne Interesse

Current Program Status Register (CPSR)

  • image_310.png
  • T-Bit
    • T = 0
      • Prozessor in Arm State
    • T = 1
      • Prozessor in Thumb State
  • Interrupt Disable Bit
    • I = 1, disables IRQ
    • F = 1, disables FIQ
  • Mode Bits
    • Spezifizieren Prozessor Mode

Übersetzungstabelle Assembler - Binärcode

image_311.png

Thumb Befehlsatz

  • zusätzlicher Befehlssatz
    • 16 Bit
    • Intern werden sie auf 32 Bit erweitert
      • Programme verbrauchen nur halben Speicher
        • weniger Register stehen zur Verfügung
      • Während Programmausführung kann zwischen ARM-32 und Thumb gewechselt werden
  • Thumb-2 ist ein gemischter 16/32 Bit Befehlssatz
  • Prozessor ARM7TDMI unterstützt sowohl ARM als auch Thumb

ARM Befehlssatz

  • Drei Befehlstypen
    • zur Datenverarbeitung (bspw. Addition)
    • Ablaufsteuerung (bspw. Verzweigungen)
    • Befehle zur Adressierung
  • Groß-Kleinschreibung wird ignoriert

ARM-Befehle: MOV

  • MOV ist ein Datentransferbefehl
    • Kopiert Daten in ein Register
  • Beispiele
    • mov r0, r1 @Inhalt von R1 wird nach R0 kopiert
    • mov r1, #0 @Zahl 0 wird nach R1 kopiert
    • mov pc, lr @PC wird auf LR gesetzt
  • Variante:
    • mvn r1, r2
      • Wendet zusätzlich zu mov ein EOR auf Inhalt von r2 an

ARM-Befehle: ADD

  • Die arithmetischen Befehle der ARM Prozessoren sind 3-Register-Befehle
    • Alle Operanden sind 32Bit
    • Das Ergebnis ist 32 Bit
    • 3 Operanden: 2 als Input, 1 als Ergebnis
  • Beispiel
    • ADD r0, r0, r3 @R0 = R0 + R3

ARM-Befehle: SUB

  • ARM-Prozessoren implementieren keine Subtraktion
    • Addition mit 2er Komplement
  • Beispiel
    • SUB r0, r0, r3 @R0 = R0 - R3 = R0 + (-R3)

ARM-Befehle: CMP

  • Befehl vergleicht zwei Werte auf Gleichheit und setzt Statusflags entsprechend
    • CMP r0, #5 @r0 == r5?
  • Dazu wird folgende Berechnung (r0=3) ausgeführt
    • CMP r0, #5 @r0-5 = 3-5 ausgeführt
      • MOV r1, #5
      • SUBS r1, r0, r1
  • Folgende Statusflags werden gesetzt
    • image_312.png

ARM-Befehle: -S

  • Setzen des Statusregisters bei arithmetischen und logischen Befehlen
  • Bedingungsbits des Statusregisters werden nur bei Test-/Compare-Befehlen automatisch gesetzt
  • Alle anderen Befehle müssen explizit setzen
  • Beispiel
    • add r0, r0, r3 @lässt Statusregister unverändert
    • subs r0, r0, #1 @schreibt alle Flags NZCV

ARM-Befehle: - {cond}

  • Jeder Befehl kann bedingt ausgeführt werden
    • Bedingung (bezogen auf vorher gesetzte Werte des Statusregisters) als Ergänzung an den Befehl angehängt
  • Beispiel
    • CMP r0, #5
    • ADDNE r1, r1, r0
    • SUBNE r1, r1, r2
    • if (r0 != 5) {r1 = r1+r0-r2}
  • NE = not equal
    • Bezogen auf die vorherigen Werte des Statusregisters

Bedingte Ausführung von Befehlen

image_313.png

Signed/unsigned

image_314.png

carry set / higher same
  • Beispiel:
    • CMP r0, r1 @berechnet R0-R1, also R0 + (-R1) und setzt NZCV
    • JCS sprungziel @springt zur Marke "sprungziel", wenn CS erfüllt ist
  • Bedeutung: Wenn unsigned >= dann C gesetzt
    • R0 = 3,R1 = 2 (nur 4-Bit Darstellung)
    • R0 = 0011 2k = 1110
    • Berechnet: 0011 + 1110 = 3 + (-2) = 0001
      • C = 1
    • R0 = 2, R1 = 3 (nur 4-Bit Darstellung)
    • R0 = 0010 R1 = 0011
    • Berechnet: 0010 + 1101 = 2 + (-3) = 1111
      • C = 0
Bedingte Ausführung LT (Less than)
  • Beispiel
    • CMP R0, R1 @berechnet R0-R1 und setzt NZCV
    • JLT sprungziel @springt zur Marke "sprungziel", wenn CS erfüllt ist
  • Bedeutung: wenn signed < dann N ungleich V
  • Beispiel 1
    • R0 = 3, R1 = 4 (nur 8 Bit)
    • R0 = 00000011 R1 = 00000100
    • Berechnet: 00000011 + 11111100 = 3 + (-4) = 11111111
      • N = 1, V = 0
  • Beispiel 2
    • R0 = -127, R1 = 2
    • R 0 = 10000001 R1 = 00000010
    • Berechnet: 10000001 + 11111110 = -127 + (-2) = 127 (?)
      • N = 0, V = 1

ARM-Befehle: Der Barrel Shifter

image_315.png

LSL: Logical Shift Left = Arithmetic Shift Left (ASL)

  • image_316.png
  • Multiplikation mit einer Zweier-Potenz
  • image_317.png
    • LSL R0, R1, #5 -> R0 = R1*2^5

LSR: Logical Shift Right

  • image_318.png
  • Division durch eine Zweier-Potenz
  • image_319.png
    • LSR R0, R1, #5 -> R0 = R1/2^5

ASR: Arithmetic Shift Right

  • image_320.png
  • Division durch eine Zweier-Potenz unter Erhaltung des Vorzeichens
  • image_321.png
    • ASR #5, positiver Operand

ROR: Rotate Right

  • image_322.png
  • image_323.png

RRX: Rotate Right Extended

image_324.png

Multiplikation mit einer Konstanten

  • mit 2^x oder als 2^x +-1 darstellen lassen
    • können in einem Zyklus durchgeführt werden
    • Beispiel: Mul mit 5
      • ADD r0, r1, r1, LSL #2
  • Durch Zusammensetzen mehrerer Instruktionen können auch komplexere Multiplikationen durchgeführt werden
    • Beispiel: Mul 10
      • ADD r0, r1, r1, LSL #2
      • LSL r0, r0, #1 @mov r0, r0, LSL#1
    • Beispiel Mul mit 119 = 17·7 = (16+1)·(8-1)
      • ADD r2, r3, r3, LSL #4 @r2 = r3·17
      • RSB r2, r3, r2, LSL #3 @r2 = r2·7

UAL (Unified Assembler Language)

  • gemeinsamer Syntax für ARM32 und Thumb
    • gleicher Code für beide Modi
  • Falls Befehl nicht umgesetzt werden kann
    • Assembler gibt Fehlermeldung aus
  • Beispiel 1
    • vorher
      • Thumb: AND R0, R1
      • ARM: AND, R0, R0, R1
    • Jetzt: AND R0, R0, R1
  • Beispiel 2
    • vorher
      • Thumb: LSL R0, R1, #2
      • ARM: MOV R0, R1, LSL #2
    • Jetzt: LSL R0, R1, #2

Arithmetische und logische Befehle

image_325.png

Binärcodierung arithmetischer und logischer Befehle

image_326.png

image_327.png

Assembler Format

  • Arithmetische und logische Befehle haben eins der beiden logischen Formate

    • <op>{<cond>}{S} -> Rd, Rn, #<32-Bit-Immidiate>
    • <op>{<cond>}{S} -> Rd, Rn, Rm, {<shift>}
  • Rd: Destination

  • Rn: Operand 1

  • Rm: Operand 2

  • Beispiel:

    • ADD r0, r1, r2
    • ADD r0, r2, #4
    • MOV r0, r1
    • ADDGTS r0, r1, r2, LSR r3

Operand 2 als Konstante (Immidiate)

  • Befehlsformat für Datenverarbeitungsbefehle reserviert 12 Bits für Operand 2
    • ergäbe einen Wertebereich von max 2^12 = 4096
    • oder aufgeteilt in Wertebereiche mit 8 Bits (0-255)
  • Diese 8 Bits können (links) rotiert werden
    • gerade Anzahl von Positionen (0, 2, 4, ..., 30)
  • Ergibt weitaus größere Abdeckung des Zahlenbereichs
    • 8 zusammenhängende Bits innerhalb des 32-Bit-Wertebereichs
    • image_328.png
  • Einige Konstanten müssen dennoch vom Speicher geladen werden
    • oder in einem Register konstruieren
  • image_329.png

Operand 2 als Konstante

  • Wertebereich
    • 0-255 [0-0xff]
      256, 260, 264, ..., 1020 [0x100-0x3fc, step 4, 0x40-0xff ror 30]
      1024, 1040, 1056, ..., 4080 [0x400-0xff0, step 16, 0x40-0xff ror 28]
      4096,4160, 4224,..,16320 [0x1000-0x3fc0, step 64, 0x40-0xff ror 26]
  • Beispiel MOV-Befehl
    • MOV r0, #0xFF000000 @MOV r0, #0xFF, 8
  • Beispiel MVN: erzeuge das bitweise 1er-Komplement
    • MOV r0, #0xFFFFFFFF @umgesetzt zu MVN r0,#0
  • Falls benötigte Konstante nicht erzeugt werden kann
    • Assembler erzeugt Fehlermeldung

Multiplikation

image_330.png

Befehle zur Ablaufsteuerung

Sprungbefehle (Branch)

  • dienen dazu den Kontrollfluss von Programmen zu kontrollieren
  • in Kombination mit Vergleichsbefehlen
    • können alle wichtigen Anweisungen (if, else, while, for, switch) darstellen
  • Ziel ist immer eine Marke (Label)
    • Assembler erzeugt Sprungadresse
  • Beispiel
  • CMP R0, #0
    BNE Marke 1
    ...
    ...
    Marke 1: MOV R5, #5
    
  • image_331.png

Sprungbefehle

image_332.png

  • Der Befehl BL führt einen Sprung aus
    • speichert die Rücksprungadresse im Link-Register r14(LR)
  • Weitere Subroutinen müssen r14(LR) im Speicher sichern
    • bspw. auf Stack und bei Rückkehr in r15(PC) wieder herstellen
  • Arbeitsregister können ebenfalls gesichert werden
    • wenn Unterprogramm diese benötigt
    • Übergabe von Parametern nach APCS-Standard
  • Beispiel
    • image_333.png

Sprungbefehle mit Mode-Wechsel (32Bit Thumb)

  • BX Rn Branch and Exchange
    • Als Argument erhält der Befehl eine Registeradresse
      • Inhalt wird in PC kopiert
        • Falls ungerade → Wechsel in Thumbmode
        • Falls gerade → Wechsel in ARM-Mode
    • Befehl BX LR ist Standardbefehl um Unterprogramme zu verlassen
      • Rücksprungadresse steht noch im Linkregister
  • BXL Label - Branch and Link with Exchange
    • Standardbefehl zum Aufruf von Unterprogrammen
    • wird in Programmen mit gemischtem 32-Bit/Thumb Code genutzt
  • BLX Rn
    • Führt Modewechsel durch
    • Speichert nächste Adresse im Linkregister

Unterprogrammaufruf mit Modewechsel

image_334.png

Befehle zur Ablaufsteuerung - Beispiele

  • image_335.png
  • Befehle MOV PC, Rd, ist nach Einführung des Thumb Befehlssatzes nicht mehr empfohlen
    • Lässt direkten Zugriff auf PC nicht zu
    • Stattdessen BX, BLX
  • Alle Sprungbefehle können bedingt ausgeführt werden
  • Offset der Sprungbefehle bis zu 32 MByte
    • FÜr größere Sprünge muss Zieladresse erst in ein Register geladen werden

Assembler-Format der Sprungbefehle

image_336.png

APCS (ARM Procedure Calling Standard)

  • Standard definiert wie Funktionen geschrieben werden sollen
    • können unabhängig geschrieben, compiliert, assembliert uns später gelinkt werden
  • Umfasst auch andere Programmiersprachen wie C
  • Definiert sind
    • Anforderungen an aufrufende/aufgerufene Funktionen
    • Einschränkungen bei der Nutzung von Registern durch Funktionen
    • Daten- und Stacklayout und Konventionen
    • C/C++ Language Bindings, shared libs, reentrant code, etc.

Parameterübergabe an Funktionen

  • Funktionsaufruf:
    • Result = fct(ARG1, ARG2, ARG3, ARG4)
      • Parameter 1-4 in Register r0-r3 übergeben
      • Rückgabewert von Funktionen steht im Register r0 oder r0/r1
  • Verwendung von Registern in der Funktion
    • r0-r3 und IP = Scratch Register
      • dürfen im Unterprogramm zerstört werden
    • Informationen in r4-r10, fp, sp dürfen nicht zerstört werden
    • Inhalt von lr wird zur Rückkehr ins aufrufende Programm benötigt
  • image_337.png