Ich möchte das Variablenzeichen testen. Mit anderen Worten, ich möchte wissen, ob eine Variable positiv oder negativ ist. Wie kann ich folgende Wenn-Dann-Sonst-Bedingungen in Assemblersprache schreiben?
if X > 0
goto A
else
goto B
Ich benutze PİC16f87x
Um meine Frage allgemeiner zu gestalten: Wenn Sie wissen, können Sie die folgenden Fragen beantworten?
ich.)
if X > Y
goto A
else
goto B
ii.)
if X >= Y
goto A
else
goto B
iii.)
if X != Y
goto A
else
goto B
Antworten:
Ich bin mit dem PIC-Mikrocontroller nicht vertraut, daher werde ich eine allgemeinere Antwort geben. (Bearbeiten: PIC-spezifische Antwort am Ende dieses Beitrags hinzugefügt)
Insbesondere kleinere Mikrocontroller wie 8-Bit und ihre Ableitungen sind in ihrer Leistung in einem einzigen Befehl begrenzt. Ein Befehl kann die Zieladresse für einen Sprung enthalten, aber nicht zwei davon,
then-else
ist also out. Sie haben nur dasif-then
Teil, aber das ist genug. Es gibt zwei Ansätze. Bei einigen Controllern können Sie zu einer bestimmten Adresse springen, wenn eine Bedingung erfüllt ist, bei anderen können Sie nur die nächste Anweisung überspringen. Im ersteren Fall sieht Ihr Code wie folgt aus:Wenn Sie nur die nächste Anweisung überspringen können, schreiben Sie so etwas wie
Der Test selbst hat auch begrenzte Möglichkeiten. Als ob Sie nicht zwei Zahlen übergeben können, um sie zu vergleichen. Sie laden den Akku mit der ersten Zahl und subtrahieren in der nächsten Anweisung die zweite Zahl. Dies führt dazu, dass Bedingungscodes wie die Null- und Übertragsflags gesetzt / gelöscht werden. Bedingte Anweisungen testen diese Flags. Also, wenn Sie schreiben möchten,
if A = B then do-equal else do-not-equal
würde dies werdenWichtig: In der Bedienungsanleitung wird angegeben, welche Bedingungscodes von einer bestimmten Anweisung betroffen sind. Zum Beispiel kann der in dem Z80 -
ld
Befehl (für „Last Akkumulator“) wird nicht alle Flags ändern. Hier wird also der Akku geladen nicht aus, um festzustellen, ob die Daten Null sind.OK bearbeiten , also habe ich einige Nachforschungen angestellt und Folgendes gefunden:
Der PIC hat nur 2 bedingte Sprunganweisungen,
BTFSS
undBTFSC
.BTFSS : Bittest F, Überspringen, wenn gesetzt
Syntax: BTFSS f, b
wobei f ein Register [0..127]
und b das Bit in dem zu testenden
Register ist [0..7] Beschreibung: Wenn das Bit im Register ist
0
Der nächste Befehl wird ausgeführt. Wenn das Bit ist1
der nächste Befehl verworfen undNOP
stattdessen a ausgeführt.BTFSC : Bittest F, Überspringen, wenn
gelöscht Syntax: BTFSC f, b
wobei f ein Register [0..127]
und b das Bit in dem zu testenden
Register ist [0..7] Beschreibung: Wenn das Bit im Register ist
1
Der nächste Befehl wird ausgeführt. Wenn das Bit ist, wird0
der nächste Befehl verworfen undNOP
stattdessen a ausgeführt.quelle
Um zu testen, ob eine Ganzzahl negativ ist, müssen Sie nur das oberste Bit testen. Wenn das oberste Bit 1 ist, ist es negativ.
Für eine 8-Bit-Ganzzahl auf einem erwähnten 8-Bit-Clabacchio können Sie nun eine Subtraktion verwenden, um den Test durchzuführen. Dies ist jedoch in der Regel nicht optimal:
Dies ist auch in C erwähnenswert, da ich gesehen habe, dass die Microchip C-Compiler dummen Code produzieren. Wenn getestet wird, ob eine 16-Bit-Ganzzahl größer als Null ist, wird buchstäblich die Assembly erzeugt, um die Ganzzahl von Null zu subtrahieren und die Flags zu überprüfen, anstatt einfach das btfss zu verwenden.
Wenn ich also PIC C schreibe, überprüfe ich immer die Assembly-Ausgabe, um festzustellen, ob sie sinnvoll aussieht. Und dann schreiben Sie normalerweise Makros, um die Operationen auszuführen. (Übrigens, ich habe diese Makros nicht wirklich überprüft, sie sind mir nur ein Rätsel).
quelle
Um ganzzahlige Vergleiche und fast alles andere in Assemblersprache durchführen zu können, müssen Sie verstehen, wie die Zahlen dargestellt werden.
Die meisten Variablen in einem kleinen eingebetteten System sind nicht signiert oder sollten es zumindest sein. Hochrangige Sprachprogrammierer, die an größere Systeme gewöhnt sind, neigen dazu, nicht darüber nachzudenken und signierte Variablen zu verwenden, wenn nur nicht signierte benötigt werden. Unsignierte sind im Allgemeinen auf niedriger Ebene einfacher zu bearbeiten.
Ihr Code ist für einen PIC 16, daher gehe ich davon aus, dass Sie den MPASM-Assembler verwenden. Ich habe eine Reihe von Makros und anderen Funktionen, die beim Vergleichen der Größe in meiner allgemeinen Include-Datei STD.INS.ASPIC helfen , die Teil meiner PIC-Entwicklungsumgebung ist . Insbesondere dienen die Makros SKIP_WLE (überspringen, wenn W kleiner oder gleich war) und SKIP_WGT (überspringen, wenn W größer als war) zum Vergleichen von Zahlen ohne Vorzeichen.
Der PIC hat ein Übertragsstatusbit namens C, das der Übertragsausgang der ALU ist. Dieses Bit kann nach einem Addieren oder Subtrahieren getestet werden, um festzustellen, ob das High-Bit der ALU übertragen wurde. Die Art und Weise, wie Subtrahieren mit Zweierkomplementzahlen funktioniert, wird das C-Bit nach einem Subtrahieren zu einem nicht geliehenen Bit. Um die Sache komplizierter zu machen, subtrahieren die PIC-Subtraktionsbefehle das W-Register vom Operanden und nicht umgekehrt. Sie müssen einige mentale Gymnastik machen, um zu verfolgen, dass C nicht ausgeliehen ist und was wirklich von dem abgezogen wurde, was und daher was ein Ausleihen tatsächlich bedeutet. Ich habe das alles einmal gemacht und das Ergebnis in diesen beiden einfachen Makros zusammengefasst, damit ich nicht jedes Mal darüber nachdenken und die Chance nutzen muss, es durcheinander zu bringen. Auf einem PIC 16 wird SKIP_WLE zum Einzelbefehl BTFSS STATUS, C, und SKIP_WGT wird zum BTFSC STATUS, C.
So würden Sie diese Makros im Code verwenden:
Es gibt viele andere nützliche Dinge in STD.INS.ASPIC. Ich habe auch einen Präprozessor , der der MPASM-Sprache viele nützliche Funktionen hinzufügt. Zum Beispiel kann es zur Erstellungszeit Gleitkomma-Berechnungen durchführen, echte Zeichenfolgenmanipulationen zum Erstellen von Symbolnamen durchführen, verfügt über eine flexiblere Makrofunktion und vieles mehr.
quelle
Ich werde vorerst nur den ersten Teil der Frage beantworten.
Sie erwähnen den Typ von X nicht - nehmen wir an, es ist ein signiertes Zeichen. Das vorzeichenbehaftete Zeichen hat b.7 == 1, wenn es negativ ist, daher müssen wir nur den Status dieses Bits überprüfen.
Hier ist ein Link zu einer netten Anleitung: Eine Anleitung zu gängigen PIC-Assembly-Programmierkonstrukten
Das obige Beispiel finden Sie auf Seite 7.
Versuchen Sie, den Rest der Antworten selbst herauszufinden. Hinweis: Clabacchios Kommentar ist sehr nützlich.
quelle
16 Bit Vergleiche
Alle Werte sind ohne Vorzeichen.
Assembler-Programmierer ändern normalerweise die Tags "else:" und "endif:" in eine eindeutige (und hoffentlich beschreibende) Bezeichnung für jede if-Anweisung. Vielleicht so etwas wie "then_in_normal_range:", "else_outside_normal_range:" und "finish_range_handling:". (Im Gegensatz zu höheren Sprachen wie Pascal und BASIC, in denen wir für jede if-Anweisung dieselben Wörter "then" und "else" und "endif" verwenden.)
Der obige Code funktioniert nur, wenn sich sowohl X als auch Y im RAM befinden. - Der PIC16f87x erfordert unterschiedliche Anweisungen, um X mit einem konstanten Wert zu vergleichen.
Eine Möglichkeit, mit 16-Bit-Vorzeichen umzugehen, besteht darin, zuerst das High-Bit umzudrehen
Verwenden Sie dann den obigen Vergleichscode. Stellen Sie später die ursprünglichen Werte wieder her, indem Sie das High-Bit erneut umdrehen
.
ps Sie können häufig eine viel schnellere Antwort auf Fragen zum PIC16f87x erhalten, indem Sie die PIClist-Website http://piclist.com/ und das Microchip-Wiki http://microchip.wikidot.com durchsuchen . Vergleiche zwischen Assemblersprachen finden Sie auf der Seite "Assemblersprachenvergleiche" im Microchip-Wiki und unter PIC Microcontroller Comparison Math Methods auf der PIClist-Website (von denen das Obige ein kleiner Auszug ist).
quelle