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ß
OOOps. Ich meinte natürlich "Das Mikrocontroller KOCH Buch"! Gruß Holger
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.