Der schnellste Weg, um in ASM ein bisschen umzuschalten

Was ist der schnellste Weg, um ein Bit 1 in MPASM für den erweiterten 14-Bit-Befehlssatz umzuschalten? (Ich arbeite mit einem PIC16F1829)

Der Code muss eigenständig sein - ich meine, dass er jederzeit aufgerufen werden kann, ohne den Wert des Bits in diesem Moment zu kennen.

Entscheidendes Kriterium ist hier die Geschwindigkeit : Ein Programm mit weniger Befehlszyklen ist besser. Die Anzahl der Befehlszyklen wird berechnet als die Zahl, wenn das Bit 0 ist + die Zahl, wenn das Bit 1 ist, dividiert durch 2.

1: mit toggle meine ich, dass der Code ähnlich wie pin=!pinin C sein muss

Was ist ein PIC16-Gerät? Nennen Sie es besser beim Kern, ich denke, Sie meinen den 14-Bit-Kern (nicht erweitert)?
@WoutervanOoijen danke, gute Idee - es ist übrigens der erweiterte Kern für diesen Chip, aber das konntest du natürlich nicht wissen.
Interessanterweise kann 'pin = !pin' in C schlimm explodieren. XC16 für PIC24 verwandelt dies in 11-12 Montageanweisungen, da es die BTG-Anweisung nicht beachtet. (GCC-Compiler zielen auf Portabilität statt Optimierung ab, daher die Notwendigkeit für Dinge wie __builtin_btg)
@Madmanguruman Ich meine, es muss dasselbe tun, nicht, dass es so schnell sein muss :)
@CamilStaps wäre es nicht besser, meine Antwort auszuschließen, indem ich sie (rückwirkend) mit einigen bearbeiteten Wörtern in der Frage ungültig mache. So wie die Frage steht, ist meine Antwort der schnellste Weg, um Ihr Ziel zu erreichen, und jemand, der zu spät zu dieser Frage kommt, mag sich fragen, warum Sie meine Antwort nicht akzeptiert haben. Ich lösche meine Antwort sehr gerne, wenn Sie dies irgendwie ausschließen können.
@Andyaka Ihr Code macht mehr als nur das Invertieren des Bits, deshalb denke ich (mit 10 Upvotern), dass seine Antwort besser ist. Um eine erneute lange Diskussion zu vermeiden, kommen Sie bitte in den Chat, um dies weiter zu besprechen.
@CamilStaps Ich lasse es gerne so, wie es ist, wenn du es bist.

Antworten (4)

Sie könnten Folgendes mit einem XOR versuchen:

movlw 0x01 ; move 0x01 to W register
xorwf lat, F ; XOR W with port & store result in port latch

Eine exklusive ODER-Operation bewahrt die Werte in Bits, wo die Bits im Arbeitsregister auf Null gesetzt sind, und invertiert die Werte, wo sie gesetzt sind. Sie könnten also dieselbe Technik auch verwenden, um mehrere Bits umzuschalten.

PeterJ, sind Sie sich des Read-Modify_write-Problems bewusst? - Update: Camil hat die Regeln präzisiert: 14-Bit Enhanced Core ==> benutze das LAT-Register anstelle des PORT!!!
Ich denke, dies ist die kürzeste Zeit, die Sie auf Geräten erhalten, die keine BTG-Anweisung unterstützen (PIC18, PIC24 usw.).
@WoutervanOoijen, ja guter Punkt, ich werde die Antwort aktualisieren

Ich bin darauf gekommen:

;                                                           Cycles if 1 | Cycles if 0
btfss    port, pin  ; skip next instruction if 1            1           | 1
goto     $+3        ; pin=0, goto PC+3                      1           | 2
bcf      port, pin  ; pin=1, clear pin and...               1           | 
goto     $+2        ;   ...proceed program                  2           |
bsf      port, pin  ; pin=0, set pin and proceed program                | 1           +
; ...                                                       ---------------------------
;                                                           5             4

Dies dauert 4 oder 5 Befehlszyklen. Geht etwas schneller?

Ich denke, PeterJs XOR ist das schickste. Aber bleiben Sie bei Ihrem Stil: Versuchen Sie, die Anleitung zum Pin-Setzen zu überspringen, anstatt um sie herum zu springen. Durch das Setzen von Pins werden die Flags nicht geändert, sodass Sie auf diese Weise sowohl die then- als auch die else-Klausel überspringen können.
@WoutervanOoijen du meinst btfss; bsf; bcf? Dann würde das Bit unabhängig vom Status gelöscht. Was meinen Sie? :)
Wenn nicht gesetzt, dann do_set, dann do_clear, sonst do_clear. Das funktioniert auch bei mir.
@Andyaka dies ist ein if not_set then do_clear else do_set
@CamilStaps Ich habe Ihre Interpretation von Wouters Kommentar kommentiert - ich war ein wenig spielerisch, weil ich nicht glaube, dass Sie die Frage getroffen haben - ich glaube, Sie möchten, dass der "Code" ein bisschen invertiert und dann das Bit beendet ODER invertiert wieder invertieren und dann beenden.
@Camile du hast Recht, ich habe deinen Code falsch interpretiert. Bleiben Sie bei der XOR-Lösung.
@Andyaka nein, das will ich nicht. Ich möchte das Bit invertieren und dann beenden. Ich will es nicht zweimal umkehren, niemals.

Was ist der schnellste Weg, um ein Bit1 in MPASM für den erweiterten 14-Bit-Befehlssatz umzuschalten? (Ich arbeite mit einem PIC16F1829)

Der Code muss eigenständig sein - ich meine, dass er jederzeit aufgerufen werden kann, ohne den Wert des Bits in diesem Moment zu kennen.

Entscheidendes Kriterium ist hier die Geschwindigkeit: Ein Programm mit weniger Befehlszyklen ist besser. Die Anzahl der Befehlszyklen wird berechnet als die Zahl, wenn das Bit 0 ist + die Zahl, wenn das Bit 1 ist, dividiert durch 2.

1: mit toggle meine ich, dass der Code ähnlich wie pin=!pin in C sein muss

Ich bin davon ausgegangen, dass das Bit, das Sie umschalten möchten, Teil eines Registers ist, das in den anderen Bits "egal" enthält, und daher würden Swap-Nibbles funktionieren. Sie haben nie gesagt, dass es so nicht funktionieren könnte, und wenn Sie so wenig Register haben, dass Sie die anderen Bits benötigen, wird eine Codeumschreibung oder ein MCU-Upgrade empfohlen.

Sie müssten zunächst 11110000 einrichten (jedes Muster würde ausreichen, wenn bn nicht gleich bn + 4 ist), aber danach jedes Mal, wenn Sie eines der verwendeten Bits invertieren möchten: -

swapf f,d

Es ist eine Ein-Zyklus-Operation und benötigt keine 1 in der Einrichtung des w-Registers.

Natürlich müssten Sie sich im Rest des Programms an diese Methode zum Ändern des Bits halten, ABER noch einmal, Sie haben nicht gesagt, dass Sie es nicht können - mit anderen Worten, BCF- oder BSF-Befehle sind verboten.

Ich dachte an Rotationen, aber sie rotieren durch Carry und das würde wahrscheinlich das Zeug beschädigen - ich habe seit über 20 Jahren keinen PIC-Code mehr geschrieben, also sollte Vergebung bei der Ablehnung im Vordergrund stehen !!!

Wenn Sie eine PIN invertieren möchten, müssen Sie den Zustand der PIN laden, also müssen Sie zuerst die Bank für PORTA auswählen. Also hier ist der Code in C:

// PORTAbits.RA5=~PORTAbits.RA5;
PORTA=PORTA ^ 0b00100000;

mit dem Ergebnis in ASM :

 MOVLB 0x0
 MOVF PORTA, W
 XORLW 0x20
 MOVWF PORTA
Sieht so aus , als wäre die akzeptierte Antwort um einen Zyklus schneller, selbst wenn der Bankschalter integriert ist (was nicht immer erforderlich ist, wenn Sie verfolgen, in welcher Bank Sie sich befinden). Natürlich liefert der C-Compiler nicht immer den am schnellsten kompilierten Code – insbesondere die kostenlosen Compiler von Microchip erzeugen sehr unoptimierten Code.