Hallo liebe Forumuser,
ich habe ein Problem und zwar ich bin im Bezug auf Assembler mit 8051
sehr schlecht und möchte mehr darüber lernen.
Meine Fragen sind:
1. Es gibt ja verschiedene Adressierungsarten, direkte-, indirekte-,
unmittelbare-, Register- und indirekte-indizierte-Adressierungen.
Wenn ich z.B. diese Anweisung sehe
Mov A, @Ri
ist es eine indirekte Adressierung, jedoch ist die Quelle ein Register
oder Ri zeigt ja auf einen direkten Bereich z.B. 90H
aber das Ziel, wo der Inhalt @Ri abgelegt wird ist A, also ein Register.
Meine Frage dazu ist wie kriege ich heraus ohne es auswendig zu lernen
welche Adressierung eine Anweisung hat, ich glaube es geht über die
Anzahl der Bytes des Befehls aber genau weiß ich es nicht.
2. Wenn ich z.B. zehn Register mit positiver 1Byte länge Addiere dann
kann es ja zu einem Überlauf kommen ich habe mir das so überlegt, dass
ich immer zwei Register zusammen zähle und dann überprüfe ob da Carry
aktiviert ist.
z.B.
Label Mnemonic
Mov A, 90H
Mov B, 91H
Add AB
JC Aufgabe
Aufgabe:
Inc DPTR
Ich weiß aber nicht ob meine Überlegung totaler Schwachsinn ist deshalb
habe ich gesagt das ich schlecht in Assembler bin und falls ich richtig
überlegt haben sollte dann denke ich das dies etwas Umständlich
Programmiert ist da man das doch auch irgendwie mit einer Schleife
machen könnte, da die Arbeitsschritte ja immer die selben sind.
Hi,
die ersten 128 Adressen für das sog. interne RAM, also die, die mit @R1
und @R0 angesprochen werden können, gehen in echtes RAM. Der Anfang
dieses RAMs ist gleichzeitig als Register (R0 bis R7) ansprechbar. Die
folgenden 128 Byte sind die Special Function Register, SFRs. Ein Blick
in das Datenblatt ist sehr zu empfehlen. Es ist, verglichen mit
moderneren Prozessoren, geradezu trivial.
Bei der Addition könnte man es z. B. so machen:
;Die ersten zwei Summanden
mov A,SummandA
add A,SummandB ;hier kann Carry entstehen
mov SummeLow,A
mov A,#0
addc A,#0
mov SummeHigh,A
;Der dritte Summand
mov A,SummeLow
add A,SummandC ;hier kann Carry entstehen
mov SummeLow,A
mov A,#0
addc A,SummeHigh
mov SummeHigh,A
;Der vierte Summand
...
statt
mov A,#0
addc A,SummeHigh
mov SummeHigh,A
ginge auch
jnc xyz
inc SummeHigh
xyz:
kuemmel schrieb:> JC Aufgabe>> Aufgabe:> Inc DPTR
Was das soll, ahne ich überhaupt nicht.
Hallo Herr Beis,
vielen Dank für Ihre Antwort, ich habe jedoch zum Add-Programm, die
stelle mit:
Uwe B. schrieb:> mov A,#0> addc A,#0> mov SummeHigh,A
Also ich überschreibe mit MOV A,#00H den Akku mit der Konstante #00H,
dann steht ja in A 00H ausser wenn das Carry gesetzt ist steht halt im
Carry eine 1.
Dann ADDC A,#00H ich addiere #00H zum A und dem Carry, da ich A zu vor
mit #00H überschrieben habe ändert sich nix und am Carry ändert sich
auch nix. Dann schreibe ich mit
MOV SummeHigh, A
den Akku direkt in ein Register ich nenne es mal einfach 21H, aber geht
denn da das Carry mit hinein oder steht jetzt wirklich in Reg(21H) das
Highbyte des Akkus drin?
Zur Frage mit der Adressierungsart habe ich heute in einem Buch, von
FRANCIS 8051 Microcontroller, gelesen, dass eine direkte Adressierung
mindestens 2 Byte groß sein muss, d.h. also alle Anweisungen die kein @
für indirekte, kein # für unmittelbare, Adressierung haben und Größer
als 1Byte sind sind indirekte Adressierungen. Wenn ich z.B. in das
Instruction Set von ATMEL für 8051 schaue sehe ich ADD A,Rn mit 1Byte
also Register-Adressierung, aber wie ist es da mit den außnahmen da gibt
es ja die Anweisung mit dem Hilfsregister B wo man denkt das es eine
Registeradressierung ist aber er ist größer als 1Byte also ist es
eine...
Ist dann eine Registeradressierung immer 1Byte groß?
Eine direkte Adressierung mindestens 2Byte groß?
Eine indirekte Anweisung immer eine indirekte Anweisung wenn sie mit @
gekennzeichnet ist, d.h. auch bei MOV @Ri, A oder ADD A,@Ri?
Neben bei habe ich noch etwas über Registerbänke gelesen es gibt ja
Register im Internenspeicher von 00H bis 1FH
wenn ich z.B. die konstante Zahl #20H in den R0 der Registerbank R0
laden will iste es ja der Befehl
MOV 00H, #20H
wenn ich den R0 der Bank R0 wählen will ist es dann
USING 00H oder?
Und bei Registerbank R1 den R0 wäre es
MOV 08H, #20H?
Und Reg.Bank R2 dann den R0 wäre
MOV 10H, #20H? usw...
ist einbißchen viel aber ich will es unbedingt wissen und die Bücher
sind sehr verwirrend manchmal steht MOV manchmal USING manchmal auch was
ganz anderes also wie wähle ich die verschiedenen R0...R7 in den
verschiedenen Registerbänken R0...R3 aus.
Hallo Kuemmel,
kuemmel schrieb:> Hallo Herr Beis,
Wir sind hier im Forum nicht so förmlich und ich heiße Uwe...
> Also ich überschreibe mit MOV A,#00H den Akku mit der Konstante #00H,> dann steht ja in A 00H
korrekt
> ausser wenn das Carry gesetzt ist steht halt im Carry eine 1.
Das hat nix mit dem Akku zu tun und Carry bleibt wie es war.
> Dann ADDC A,#00H ich addiere #00H zum A und dem Carry, da ich A zu vor> mit #00H überschrieben habe ändert sich nix und am Carry ändert sich> auch nix.
Nein. Du addierst: Akku = Akku + #0 + Carry. Wenn Carry = 1 war, wird
der Akku 1 größer werden. Wenn der Akku nicht überläuft, wird Carry
anschließend 0 sein.
> Dann schreibe ich mit>> MOV SummeHigh, A>> den Akku direkt in ein Register ich nenne es mal einfach 21H, aber geht> denn da das Carry mit hinein oder steht jetzt wirklich in Reg(21H) das> Highbyte des Akkus drin?
Das Schreiben hat nichts mit Carry zu tun. Und es ist kein Register,
sondern ein Speicherplatz im internen Memory.
--> Schau dir in der Befehlsübersicht an, welche Befehle das Carry
verändern können!
> Zur Frage mit der Adressierungsart habe ich heute in einem Buch, von> FRANCIS 8051 Microcontroller, gelesen, dass eine direkte Adressierung> mindestens 2 Byte groß sein muss, d.h. also alle Anweisungen die kein @> für indirekte, kein # für unmittelbare, Adressierung haben und Größer> als 1Byte sind sind indirekte Adressierungen.
Ich glaube, dass das so stimmt, zumindest weitgehend. Nur dass du mit
dem letzten Satzteil "sind indirekte Adressierungen." genau das
Gegenteil vom ersten schreibst. Oder habe ich den komplexen Satz falsch
verstanden?
> Wenn ich z.B. in das> Instruction Set von ATMEL für 8051 schaue sehe ich ADD A,Rn mit 1Byte> also Register-Adressierung, aber wie ist es da mit den außnahmen da gibt> es ja die Anweisung mit dem Hilfsregister B wo man denkt das es eine> Registeradressierung ist aber er ist größer als 1Byte also ist es> eine...
B ist ein SFR und wird über 2-Byte-Befehle angesprochen (außer MUL AB).
> Ist dann eine Registeradressierung immer 1Byte groß?
Register sind die 8 Speicheradressen im internen RAM die sich mit
1-Byte-Befehlen ansprechen lassen.
Special Function Register (SFRs) sind die 128 Speicheradressen im
internen RAM >= 128.
Die 128 Speicheradressen im internen RAM < 128 ist internes RAM.
Aaaaber: Es gibt auch internes RAM >= 128. Das kann nur indirekt
adressiert werden. Die selben Adresse, aber direkt adressiert, gehen auf
die SFRs.
> Eine direkte Adressierung mindestens 2Byte groß?
Ja.
> Eine indirekte Anweisung immer eine indirekte Anweisung wenn sie mit @> gekennzeichnet ist, d.h. auch bei MOV @Ri, A oder ADD A,@Ri?
Ja, @Ri (i kann 0 oder 1 sein) ist ein 1-Byte Befehl.
> Neben bei habe ich noch etwas über Registerbänke gelesen es gibt ja> Register im Internenspeicher von 00H bis 1FH
Abhängig von den Bits RS1:RS0 im SR liegen die 8 Register auf den ersten
32 Adressen des internen RAMs.
> wenn ich z.B. die konstante Zahl #20H in den R0 der Registerbank R0> laden will iste es ja der Befehl>> MOV 00H, #20H
Damit schreibst du in das interne RAM Adresse 0. Dort steht nur dann R0,
wenn im SR die Bits RS1:RS0 auf 00 stehen.
> wenn ich den R0 der Bank R0 wählen will ist es dann> USING 00H oder?
Dann nimmt der Assembler an, dass R0 auf 00h liegt.
> Und bei Registerbank R1 den R0 wäre es
Was soll das heißen???
> MOV 08H, #20H?
Schreibt auf das interne RAM Adresse 8. Dort steht nur dann R0, wenn im
SR die Bits RS1:RS0 auf 01 stehen.
> Und Reg.Bank R2 dann den R0 wäre>> MOV 10H, #20H? usw...
SR Bits RS1:RS0 auf 10
Was du wahrscheinlich noch nicht erkannt hast: Mit dem Befehl
MOV R0,#45
schreibst du in R0, egal, wo das gerade steht. Und das kostet nur 1 Byte
und 1 Zyklus.
> ist einbißchen viel aber ich will es unbedingt wissen und die Bücher> sind sehr verwirrend manchmal steht MOV manchmal USING manchmal auch was> ganz anderes also wie wähle ich die verschiedenen R0...R7 in den> verschiedenen Registerbänken R0...R3 aus.
USING ist eine Assembler-Anweisung, kein Prozessor-Befehl.
Hat's geholfen?
Ein schriftlichen 1-Mann-Grundlagenkurs in irgendwas kann nicht der Sinn
eines Forums sein, normalerweise mache ich das auch nicht. Zumal die
Dokumentation, zumindest die, die ich kenne, ebenso wenig kompliziert
wie der Prozessor ist. Na ja, aber für einen Anfänger... Wohl doch
verwirrend.
Lesen, lesen, lesen und: _Beispiele studieren!_
Grüße, Uwe
kuemmel schrieb:> Meine Frage dazu ist wie kriege ich heraus ohne es auswendig zu lernen> welche Adressierung eine Anweisung hat
@ = indirekt
# = Zahl
ohne = direkt
Push/Pop = indirekt
indirekt: RAM 0..127 (8051) bzw. 0..255 (8052)
direkt: RAM 0..127 oder SFR 128..255
Man sollte das Instruction Manual neben sich haben. Fuer jeden Befehl
ist dort neben der Funktionalitaet, der Aufbau und die Laenge des
Befehls, Anzahl Zyklen, die betroffenen Flags und der OpCode drin. Und
eigentlich ist keine Information dort fuer NICHTS.
Hallo Uwe,
ich heiße Josef danke dir für deine Antworten.
Uwe B. schrieb:> B ist ein SFR und wird über 2-Byte-Befehle angesprochen (außer MUL AB)
also ist dann jeder Befehl der B anspricht 2-Byte groß und somit keine
Registeradressierung bzw. immer eine direkte Adressierung (außer bei
Kennzeichen @# usw und bei MUL AB)?
Uwe B. schrieb:> Oder habe ich den komplexen Satz falsch> verstanden?
Nein du hast den Satz nicht falsch verstanden ich habe mich verschrieben
es sollte direkt heißen.
Uwe B. schrieb:> Abhängig von den Bits RS1:RS0 im SR liegen die 8 Register auf den ersten> 32 Adressen des internen RAMs.
das heisst die 32 Adressen werden in vier Bänke aufgeteilt R0 gibt es
also vier mal einmal in RS0 einmal in RS1 usw...
Uwe B. schrieb:> wenn im SR die Bits RS1:RS0 auf 00 stehen
ich muss also erstmal das Bit für R0 in RS1 aktivieren damit ich R0 von
RS1 verwenden kann, d.h. mit
SETB PSW, 00H ; R0 von RS0 aktiviert
SETB PSW, 08H ; R0 von RS1 aktiviert
oder
SETB PSW, RS0 ; RS0 ist aktiviert
Uwe B. schrieb:> Hat's geholfen?
Danke dir mit der Addition hast du mir geholfen ich fange langsam an es
zu verstehen, jedoch habe ich vier Bücher
-Mikrocomputertechnik mit der 8051 Controller-Familie, Jürgen Walter
-Mikrocontroller Praxis, Heesel/Reichstein
-Kompaktkurs Mikrocontroller, S.Limbach
-MC-Tools 2, O. Feger
ich schaue in alle rein ich habe auch schon gelernt welche verschiedenen
SPeicher im SFR stehen, z.B. A, B, CY, Ports, Interrupts, Timer usw...
jedoch steht da nicht wie man diese aktiviert.
Beispiel ich würde auch gerne wissen wie man in Assembler den
Interrupt-Flag aktiviert also in der Programmierform das ich zwei
Interruptflags setzen muss das weiß ich das ist der EA und ES?
Hallo Kümmel, (an dieser Stelle könnte dein Name stehen :-) )
ist zwar schon etwas her, dass du deine Fragen hier gestellt hast. Ich
hätte bezüglich eines guten Lehrbuches aber einen Tipp: "Das
Mikrocontrollerbuch" von Andreas Roth war für mich ein sehr gut
verständliches Hilfsmittel zum erlernen und begreifen der 51er und der
Assemblersprache bzw. Syntax!
Es kann sein, dass dieses Buch nicht mehr erhältlich ist, aber
vielleicht gut gebraucht bei A......
Gruß
Das habe ich auch. Man kann es als den 2. Teil dazu bezeichnen. Hier
sind dann spezielle Funktionen und Softwarebeispiele für diverse
Opperationen beschrieben. Als Einsteigerbuch halt weniger geeignet.