Warum wurde dieser Code nicht viel einfacher geschrieben?


8

Ich bin bei der Arbeit an der Assemblersprache auf eine Frage gestoßen. Hier ist die Frage:

Angenommen, Bit P2.2 wird zur Steuerung eines Außenlichts und Bit P2.5 als Licht in einem Gebäude verwendet. Zeigen Sie, wie Sie das Außenlicht einschalten und das Innenlicht ausschalten.

Lösung gegeben:

SETB C            ; CY = 1
ORL C, P2.2       ; CY = P2.2 ORed w/ CY
MOV P2.2, C       ; turn it on if not on
CLR C             ; CY = 0
ANL C, P2.5       ; CY = P2.5 ANDed w/P2.5
MOV P2.5,C        ; turn it off if not off

Ich hatte nur das Gefühl, dass das Codieren genauso funktioniert:

SETB P2.2
CLR P2.5

Was stimmt damit nicht?


2
Vielleicht nur Didaktik - zeigt, wie man das Carry-Bit als Akkumulator verwendet. Es gibt keinen Vorteil, den ich in diesem speziellen Fall sehen kann. Dies sieht aus wie 8051-Assemblycode.
Spehro Pefhany

@SpehroPefhany Aber soweit ich weiß, wird das Acc-Register in einigen Fällen verwendet, da es das einzige Register ist, das einige Anweisungen wie DA, RR, RL usw. unterstützt. Ich glaube nicht, dass dies hier der Fall ist. Liege ich falsch?
İlker Demirel

Der Carry ist ein bisschen breit. In einigen Fällen möchten Sie es möglicherweise als Akkumulator verwenden, z. B. zur Auswertung der Kontaktplanlogik.
Spehro Pefhany

Antworten:


11

Sie haben Recht damit, dass der Code, den Sie anzeigen, albern erscheint. Vielleicht kann jeder Computer, auf dem dies ausgeführt wird, keine sofortigen Operationen ausführen, um Bits an E / A-Ports zu setzen, und deshalb ist so etwas wie SETB P2.2 nicht möglich.

Das CY-Bit immer noch auf 1 zu setzen und dann irgendetwas hinein ODER zu ordnen, ist einfach albern. Das gleiche gilt für das Setzen des CY-Bits auf 0 und das UND-Verknüpfen von etwas. Natürlich kann das CY-Bit direkt in ein E / A-Pin-Bit kopiert werden, da der Code dies tut. Dies sollten höchstens 4 Anweisungen sein, schon gar nicht 6.


Ich kann also sagen, dass ich, wenn ein Bit bitadressierbar ist, Bitanweisungen für jedes Bit verwenden darf, oder?
İlker Demirel

1
@ İlk: Nicht unbedingt. Es kann Einschränkungen geben, da die Bitbefehle nur für bestimmte Register, bestimmte "nahe" Speicher und dergleichen funktionieren. Ohne Kenntnis des Prozessors können wir nicht sicher sagen, ob SETB P2.2 möglich gewesen wäre. SETB C gefolgt von MOV P2.2, C ist jedoch eindeutig möglich.
Olin Lathrop

1
@OlinLathrop: Der Prozessor ist mit ziemlicher Sicherheit eine 8051-Variante, und der Befehlssatz für diese würde die Verwendung der gleichen Speicherorte SETB bitund CLR bitAnweisungen wie für ermöglichen MOV bit,C. Wenn Sie diskrete Anweisungen zum Lesen eines E / A-Ports verwenden, den Wert aktualisieren und zurückschreiben, erhalten Sie eine andere Semantik als bei Verwendung von Lese-, Änderungs- und Schreibanweisungen. Die bitweisen Anweisungen verwenden alle dieselbe Lese-, Änderungs- und Schreibsemantik für I. / O-Ports.
Supercat

9

Der Code ist mit ziemlicher Sicherheit für einen Prozessor gedacht, der den 8051-Befehlssatz verwendet. Auf diesem Prozessor hat die von Ihnen angegebene Codevariante den gleichen Effekt wie das Original, außer dass sie schneller ausgeführt wird. Das Ausführen von "ORL C, P2.2", wenn der Übertrag eingestellt ist, hat keinen beobachtbaren Effekt, außer dass eine bestimmte Anzahl von Zyklen verschwendet wird (zwei CPU-Zyklen mit insgesamt 24 Taktzyklen auf einem 8051, wenn ich mich richtig erinnere; wahrscheinlich eine andere Anzahl auf einigen anderen Varianten) . Ebenso bei der Ausführung von "ANL C, P2.5", wenn der Übertrag klar ist. Obwohl es einige Arten von Prozessoren gibt, bei denen eine Anforderung zum Lesen einiger E / A-Speicherorte einen beobachtbaren Effekt haben würde, glaube ich nicht, dass ein Prozessor im 8051-Stil jemals ein solches Verhalten für bitadressierbare E / A-Speicherorte hatte weniger für Bits von P2.

Vielleicht war der Zweck des Codes, die ORL C,bitund ANL C,bitAnweisungen zu demonstrieren , aber dies scheint ein seltsames Beispiel zu sein, um sie zu demonstrieren.


6

Der angegebene Assemblycode wird wahrscheinlich vom Compiler generiert. Es ist die nicht optimierte Version der folgenden C-Anweisungen, wobei P2_2und die bitadressierbaren P2_5Objekte sind:

P2_2 |= 1;
P2_5 &= 0;

Dies mag äquivalent zu P2_2 = 1;und P2_5 = 0;erscheinen, ist es aber nicht, wenn die bitadressierbaren Register flüchtige Objekte sind. Eine Lese-, Änderungs- und Schreiboperation für ein flüchtiges Objekt muss das Lesen und das Schreiben in dieser Reihenfolge ausführen. Dies stellt sicher, dass alle Nebenwirkungen beim Lesen oder Schreiben des Registers tatsächlich auftreten.

Obwohl ich kein 8051-Bit-adressierbares Register mit Nebenwirkungen kenne, kann ein Compiler nicht davon ausgehen, dass es keines gibt oder nie geben wird.


1
Guter Punkt, um möglicherweise vom Compiler generiert zu werden. Dann wird jedoch die Frage gestellt, warum jemand P2_2 | = 1 anstatt nur P2_2 = 1 schreiben würde.
Olin Lathrop

3

Der wirkliche Unterschied zwischen diesen kann subtil sein.

In Ihrer vereinfachten Antwort lautet die Logik, den Port zu lesen, den Bitwert zu setzen oder zu löschen und ihn dann wieder in den Port zu schreiben. Beachten Sie, dass der gesamte Port hier neu geschrieben werden kann.

Die Lösung verwendet andererseits den MOV-Bitbefehl, der auf eine ziemlich andere Weise arbeiten kann.

Ohne auf die Details des hier verwendeten Teils einzugehen, ist es schwierig festzustellen, ob es einen Unterschied gibt oder ob es darauf ankommt.

Oder es könnte einfach sein, dass der Ausbilder beschlossen hat, Sie zum Nachdenken zu bringen ... was schließlich ... sein richtiger Job ist.


0

Die einzige Antwort ist, dass der Prozessor 1-Bit-Befehle nicht direkt unterstützt. Wenn das Übertragsbit verwendet wird, weiß es jedoch, dass nur ein Bit manipuliert wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.