Forum: Mikrocontroller und Digitale Elektronik Assembler Befehl CP/CPC


von Autor (Gast)


Lesenswert?

Hallo,

ich habe ein kleines Verständnisproblem bezüglich den Befehlen CP und 
CPC des Atmega88.

Unser Dozent gab uns folgende Assembler Übungsaufgabe:

Entwickeln sie in Assembler ein möglichst kurzes Unterprogramm für den 
Mega88, das zwei 16bit Zahlen Z1 und Z2 miteinander vergleicht. Das 
Unterprogramm übergibt das Ergebnis in Register R16 an das 
Hauptprogramm. Das Unterprogramm soll "Vergleiche" heißen und keine 
Register bis auf R16 verändern.
Das Low-Byte von Z1 steht in R24, das High-Byte in R25.
Das Low-Byte von Z2 steht in R26, das High-Byte in R27.
Das Unterprogramm soll eine 1 zurückgeben für den Fall das Z1>Z2 ist, 
eine 0 zurückgeben wenn beide Zahlen gleich sind und 0x80 zurückgeben 
wenn Z1<Z2.



Lösung:


Vergleiche:
cp R24,R26
cpc R25,R27
breq gleich
brlt kleiner
ldi R16,1
rjmp back


kleiner:
ldi R16,0x80
rjmp back


gleich:
ldi R16,0


back:
ret


Ich bin jetzt der Meinung dass das Programm NICHT Funktioniert sobald 
R24 größer als R26 ist. Denn dann würde das Carry Flag nicht gesetzt 
werden. Wenn nun aber die beiden Highbytes identisch sind, werden 
jeweils nur die High-Bytes ohne Carry verglichen (da das Carrybit 0 ist) 
und das Zero Flag wird dann dementsprechend gesetzt.
Somit würde das Programm zu Gleich springen, obwohl die Zahlen nicht 
identisch sind?

Leider habe ich momentan nicht die Möglichkeit das ganze zu testen...



Zusätzlich hätte ich noch eine andere Frage.

Mit dem Befehl "out" lassen sich nur sämtliche I/O Register und 
manche?!?! Special Function Register beschreiben?
Mir ist aufgefallen dass ich z.B. das EICRA (External Interrupt Control 
Register A) nicht damit beschreiben kann, sonder nur mit dem Befehl STS.
Wo genau liegt jetzt der Unterschied?



Danke für eure Hilfe

von MWS (Gast)


Lesenswert?

Vertausch' Rr und Rd.

von MWS (Gast)


Lesenswert?

Autor schrieb:
> Mit dem Befehl "out" lassen sich nur sämtliche I/O Register und
> manche?!?! Special Function Register beschreiben?

Jedes Register, dessen Adresse >A< dieser Bedingung entspricht: 0 ≤ A ≤ 
63
AVR 8-bit Instruction Set, zu beziehen bei Atmel.

von c-hater (Gast)


Lesenswert?

Autor schrieb:

> Ich bin jetzt der Meinung dass das Programm NICHT Funktioniert sobald
> R24 größer als R26 ist. Denn dann würde das Carry Flag nicht gesetzt
> werden. Wenn nun aber die beiden Highbytes identisch sind, werden
> jeweils nur die High-Bytes ohne Carry verglichen (da das Carrybit 0 ist)
> und das Zero Flag wird dann dementsprechend gesetzt.
> Somit würde das Programm zu Gleich springen, obwohl die Zahlen nicht
> identisch sind?

Mal abgesehen davon, daß die Lösung nicht 100%ig der Aufgabenstellung 
entsprecht, bezüglich des von dir als problematisch angesehenen Teil 
kann ich dich aber beruhigen, das funktioniert schon so, wie es soll. 
Siehe "AVR instruction set reference", insbesondere bezüglich des 
unterschiedlichen Verhaltens von cp und cpc bezüglich des 
Zero-Flags...

> Leider habe ich momentan nicht die Möglichkeit das ganze zu testen...

Wieso nicht? Du kannst doch dein Problem posten, hast also einen 
Computer. Dann kannst du auch einen AVR-Simulator ausführen.

> Zusätzlich hätte ich noch eine andere Frage.
>
> Mit dem Befehl "out" lassen sich nur sämtliche I/O Register und
> manche?!?! Special Function Register beschreiben?

Nicht alle. Es gibt bei größeren AVRs "memory mapped"-IO-Register, die 
sich über IN/OUT nicht erreichen lassen.

> Wo genau liegt jetzt der Unterschied?

Der IN/OUT-Opcode hat nur fünf Bit zum Codieren der Adresse. Gibt es 
mehr als 32 IO-Adressen, muß man sich also was anderes einfallen lassen, 
um "überzähligen" erreichen zu können.

Da hilft die Tatsache, daß sowieso sämtliche IO-Register (und auch 
sämtliche MCU-Register) immer auch über den SRAM-Adressraum erreichbar 
sind. Da braucht's also gar keine besonderen Klimmzüge. Die Besonderheit 
bei "memory mapped"-IO-Registern besteht also allein darin, daß sie 
ausschließlich über den SRAM-Adressraum erreichbar sind.

von Autor (Gast)


Lesenswert?

Das vertauschen würde in dem speziellen Fall das richtige Ergebnis 
bewirken. Wenn dann aber die andere Zahl wieder größere ist, geht es 
doch wieder nicht, oder?

Liege ich in der Annahme richtig, dass ich sicherheitshalber STS immer 
benutzen kann? In der Klausur haben wir leider kein Datenblatt, weshalb 
ich somit nicht weiß ob das zu beschreibende Register zwischen 0 und 63 
liegt...


STS    k, Rr    Store Direct to Data Space
OUT    A, Rr    Out to I/O Location

k ist demnach die Adresse des Registers? Durch die "m88def.inc" kann ich 
demnach auch EICRA ansprechen, da der Compiler die Adresse des Registers 
automatisch einsetzt?

von MWS (Gast)


Lesenswert?

c-hater schrieb:
> Der IN/OUT-Opcode hat nur fünf Bit zum Codieren der Adresse. Gibt es
> mehr als 32 IO-Adressen, muß man sich also was anderes einfallen lassen,
> um "überzähligen" erreichen zu können.

Nicht wwirklich, es sind 6 Bits entsprechend 0-63, sonst würde sich das 
klassischerweise an 0x3F befindliche SREG nicht mit IN/OUT erreichen 
lassen.

Mit SBI/CBI verwechselt?

von Autor (Gast)


Lesenswert?

c-hater schrieb:
> Da hilft die Tatsache, daß sowieso sämtliche IO-Register (und auch
> sämtliche MCU-Register) immer auch über den SRAM-Adressraum erreichbar
> sind. Da braucht's also gar keine besonderen Klimmzüge. Die Besonderheit
> bei "memory mapped"-IO-Registern besteht also allein darin, daß sie
> ausschließlich über den SRAM-Adressraum erreichbar sind.

Das heißt ich kann sämtliche Register über STS beschreiben?

Also als Beispiel so:

.DEF Tmp = R16

ldi Tmp,0xFF
STS DDRD,Tmp


Danke für eure Hilfe.

von MWS (Gast)


Lesenswert?

Das Vertauschen der Register entspricht der Forderung, lies im 
Instruction Set den Teil, der das Verhalten des Carry Flags beschreibt.

> Das heißt ich kann sämtliche Register über STS beschreiben?

STS/LDS, oder LD/ST geht immer, aber die Adresse für den IO Bereich bis 
0x3F ist um 0x20 höher, das sind die Adressen, die in der Register 
Summary des jeweiligen uC in Klammern gesetzt sind. Was auch kein Wunder 
ist, denn an 0x00..0x1F sitzen R0..R31

von Peter D. (peda)


Lesenswert?

Autor schrieb:
> STS DDRD,Tmp

Nein, dann ist die vordefinierte Adresse falsch.

Zu der 1. Frage:
Sind die Zahlen signed oder unsigned?
BRLT, BRGE testen signed, BRLO, BRSH unsigned.

Für unsigned:
1
Vergleiche:
2
cp R24,R26
3
cpc R25,R27
4
ldi r16, 0
5
breq _verg1
6
ldi r16, 0x80
7
brsh _verg1
8
ldi r16, 1
9
_verg1:
10
ret

von c-hater (Gast)


Lesenswert?

MWS schrieb:

> Mit SBI/CBI verwechselt?

Jepp.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.