2017-01-05 5 views
0

Ich bin ziemlich neu in ARM und suche einen Wert in einem Register mit einer Auswahl bekannter Hexwerte zu vergleichen. Im Moment habe ich diese Anweisungen durch die Verwendung einzelner CMP tue so dass der Code wie folgt aussieht:ARM THUMB2 Funktion zum Vergleichen mit einer Anzahl von Werten

;stuff 

CMP r2, #0x41 

CMP r2, #0x45 

CMP r2, #0x49 

etc... 

dies deutlich wird ziemlich umständlich nach einer Weile und ich denke, es muss ein Weg, um den Wert in r2 zu vergleichen, um zu eine Anzahl von Hex-Werten auf einmal.

Aplogies für die Newbie Frage, danke für die Hilfe im Voraus.

+0

Lassen Sie die Werte, mit denen Sie vergleichen möchten, in einem Array und durchlaufen Sie sie. –

+0

Sie können einen binärähnlichen Vergleichsbaum erstellen. – EOF

+0

das ist die Art der Assemblersprache, sie haben nicht ein Register zu vielen Dingen auf einmal Anweisung, sicherlich nicht für ein RISC, vielleicht ein CISC, aber ich bezweifle es (sagen, dass jemand dazu führen könnte, die Ausnahme zu zeigen). Sie können vielleicht die Anzahl der Vergleiche reduzieren, aber der Daumen hat keinen Vergleich zu vielen Anweisungen. –

Antwort

0

Im Allgemeinen betrachten Sie den gültigen Wertebereich.

  1. Überprüfen Sie, ob der Wert im Bereich liegt.
  2. Den niedrigsten Wert vom Register subtrahieren.
  3. Geänderten Wert als Array-Index verwenden; Array kann einen Wertschlüssel haben oder nur ein Ja/Nein sein.

Schritt 2,3 werden nur benötigt, wenn einige Werte im Bereich nicht gültig sind und das Array ziemlich dicht gepackt sein sollte, was für Ihr zweistelliges Hex das sein sollte.

# Range check (step 1) 
    cmp r2, #hi_val 
    bhi out_of_range 
    cmp r2, #low_val   ; optimized version is subs r2, r2, #low_val 
    blo out_of_range 

    # Adjust value (step 2) 
    sub r2, r2, #low_val  ; removed in optimized version. 

    # Get check from array (step 3) 
    adr r0, key_array 
    ldrb r0, [r0, r2] ; base of array + adjusted value. 
    bx lr   ; return w. result in r0. 

# Handle not in range. 
out_of_range: 
    mov r0, #-1 
    bx lr   ; use 0xffffffff for out of range. 

# This is a constant array included with the code. 
key_array: 
    .byte 1, 1, 0, 1, 1, 1, 0, 0, 1, 1 # etc. 

Offensichtlich Ihre key_array muss mit Ihrem Anwendungsfall gültig sein geändert werden. Die Bedingungscodes ändern sich leicht für vorzeichenbehaftete und vorzeichenlose Werte.

Wenn key_array alle Einsen für den binären Fall sind, dann sind die Schritte zwei und drei nur return 1;. Wenn der Wert low_val Null ist, müssen Sie nicht subtrahieren (oder eine Überprüfung im unteren Bereich durchführen). Die key_array sollte die Größe hi_val - low_val + 1 haben oder Ihre Bereichsüberprüfungslogik kann sich ändern.

Dieser Mechanismus wird für viele "ctype" -Funktionen wie ispunct verwendet, aber Sie können bis zu acht Werte in einem Byte speichern und eine Bitmaske verwenden, um diejenige zu erhalten, an der Sie interessiert sind 'C' und verwende einen Compiler. Es ist möglich, nur ein Register zu verwenden (R0 ist EABI-kompatible Funktion), aber dann ist die Fehlerbehandlung auch gemischt und weniger klar.

Verwandte Themen