Direktiven des 8051
-
Hallo!
Es geht um den Microcontroller 8051. Wir lernen gerade die Direktiven des 8051.
Erstmal zu den Direktiven:
main.asm:
MAIN segment code ;Gen. Codesegment für das Hauptrogramm STACK segment idata ;idata Segment für den Stack DATEN segment data ;data Segment für den Speicherblock blocksize equ 7 stacksize equ 10 ;-------------------------------------------- ;Absolutes Codesegment für Programmstart bei 0 cseg at 0 jmp MAIN ;-------------------------------------------- ;Stacksegment rseg STACK ds stacksize ; Stack reserviert ;-------------------------------------------- ;Datensegment rseg Daten block: ds blocksize ; Datenblock reservieren ;-------------------------------------------- rseg MAIN EXTRN CODE (checksum) ; Hauptprogramm ; ------------- mov sp,#STACK-1 ; Stackpointer laden mov r0,#block ; Init SPeicherblock für Test mov r1,#blocksize mov b,#200 ; Block mit 200, 201 .... gefüllt l1: mov @r0,b inc r0 inc b djnz r1,l1 mov r0,#block ; Init Input-Parameter mov r1,#blocksize call checksum jmp $ end
sub.asm:
; Unterprogramme ; -------------- PUBLIC checksum SUB1 segment code rseg SUB1 checksum: clr a mov dptr,#0 loop: add a,@r0 inc r0 jnc next inc dph next: djnz r1,loop mov dpl,a ret end
Also das Programm hab nicht ich geschrieben. Ich hab das Programm bekommen und will davon lernen.
Ich kenne mich mit alle Befehlen aus von den Arethmetischen-Befehle bis zu den Jump-Befehlen. Nur hab ich NULL Ahnung wie die Direktiven(cseg etc.) hier funktionieren.
Wir haben das Programm einfach so bekommen, d.h. was ist die Grundidee von diesem Programm?
Welcher Befehl hier Verknüpft die 2 asm-Files? Den in C inkludiert man jenes File in dieses File.
Also hier noch zusammengefasst:
Was ist die Grundidee des Programms, was ist die Funktion?
Was macht cseg, rseg(STACK, DATEN, MAIN?) und ds in diesem Programm?
Welche Befehle verknüpfen die 2 asm-files?
Was machen diese 3 Befehle?:MAIN segment code STACK segment idata DATEN segment data
Der Befehl equ speichert eine Zahl in in irgendein Wort richtig? Zu was ist das gut? Zur besseren Übersicht?
Was hat "jmp MAIN" für einen Sinn?
Warum schreibt man in Zeile 24 "block:"?
Wie funktioniert das: "EXTRN CODE (checksum) " und "PUBLIC checksum"?Sorry für diese viele Frage, aber ich möchte mich einfach auskennen, hab ja schon gegoogelt, aber nicht so wirklich passendes gefunden.
Ich wäre euch also sehr dankbar wenn einer sich das anschauen könnte!
Danke im voraus
!
Mit freundlichen Grüßen
assembler_anfänger
-
assembler_anfänger schrieb:
Es geht um den Microcontroller 8051. Wir lernen gerade die Direktiven des 8051.
Nein. Ihr lernt die Direktiven eines 8051-Assemblers. Die stehen meist im Manual des jeweiligen Assemblers. "8051" bezeichnet nur grob die Prozessorfamilie, die sich aber in den letzten 30 Jahren gewaltig gewandelt hat. Die Bezeichnung "8051" ist etwa so genau wie "VW Golf". Übertragen hast Du gerade gesagt: "Wir lernen die Straßenverkehrsregeln für einen VW Golf".
Leider teilst Du weder Prozessor noch Assembler mit, weswegen die nachfolgenden Erläuterungen mit Vorbedacht zu betrachten sind.
Was ist die Grundidee des Programms, was ist die Funktion?
Die Grundidee des Programms ist, dass Du was lernst, und die Funktion des Programms, den Prozessor ganz kurz zu beschäftigen und dann in einer Endlosschleife zu verharren. Herauszukriegen, was die Funktion checksum macht, überlasse ich Dir.
Was macht cseg, rseg(STACK, DATEN, MAIN?) und ds in diesem Programm?
Es sind Hinweise an den Assembler, zu welchem Typ von Daten der nachfolgende Block gehört. Später kann ein weiteres Programm - der Linker - anhand der Hinweise die Blöcke (Segmente) sinnvoll ordnen.
Welche Befehle verknüpfen die 2 asm-files?
EXTRN und PUBLIC. Die 2 ASM-Dateien sind erst einmal gar nicht verknüpft, sondern werden separat zu Object-Dateien "assembliert". Diese Object-Dateien werden dann vom Linker zusammengeführt und zum Endprodukt verarbeitet. Der Linker ersetzt dabei unbekannte Adressen im einen Modul ("EXTRN") durch bekanntgemachte Adressen im anderen Modul ("PUBLIC").
Was machen diese 3 Befehle?:
MAIN segment code STACK segment idata DATEN segment data
Ganz genau kann man das ohne Kenntnis des Assemblers nicht sagen. Ich denke mal, dass es den Segmenten einen Namen gibt und insbesondere ihre Reihenfolge festlegt.
Der Befehl equ speichert eine Zahl in in irgendein Wort richtig? Zu was ist das gut? Zur besseren Übersicht?
EQU speichert erstmal gar nichts, sondern ist eine Ersetzungsregel ganz ähnlich dem #define in C. Überall, wo dann dieses Symbol auftaucht, wird es durch den EQU-Wert ersetzt. Das dient zur Übersicht, aber noch mehr zur besseren Wartung: Wenn Du Dich z. B. entschließt, den Block zu vergrößern, dann musst Du das nur einmal in der EQU-Zeile und nicht überall in allen Dateien.
Was hat "jmp MAIN" für einen Sinn?
Beim Einschalten springt der µC zur Adresse 0 und fängt an, den dortigen Code auszuführen. An dieser Stelle muss also Code stehen ("cseg at 0"). Da sich dann üblicherweise die Interrupttabelle anschließt, ist es ungeschickt, das eigentliche Programm (MAIN) dort abzulegen. Deshalb ist dort nur ein Befehl, der zum Hauptprogramm springt (jmp MAIN).
Warum schreibt man in Zeile 24 "block:"?
Das ist ein Label, damit man den Speicherbereich wiederfinden kann. Entspricht in diesem Fall der C-Definition "char block[blocksize];".
Wie funktioniert das: "EXTRN CODE (checksum) " und "PUBLIC checksum"?
EXTRN teilt dem Assembler mit, dass es diese Funktion in dieser Datei nicht gibt und PUBLIC teilt dem Assembler mit, dass diese Funktion auch anderen (Object-)Dateien zur Verfügung gestellt werden soll.
viele grüße
ralph
-
rkhb schrieb:
Leider teilst Du weder Prozessor noch Assembler mit, weswegen die nachfolgenden Erläuterungen mit Vorbedacht zu betrachten sind.
Also programmiert wird mit dem Programm uvision3 und er uC ist wie gesagt von der der Baugruppe 8051. Am Anfang stellen wir da immer irgendeinen von Atmel oder INTEL ein. Wir haben nocht nicht wirklich gelernt was für einen GENAU wir nehmen sollen. Ich hoffe euch/dir hilft das weiter.
Was macht cseg, rseg(STACK, DATEN, MAIN?) und ds in diesem Programm?
Es sind Hinweise an den Assembler, zu welchem Typ von Daten der nachfolgende Block gehört. Später kann ein weiteres Programm - der Linker - anhand der Hinweise die Blöcke (Segmente) sinnvoll ordnen.
Das verstehe ich überhaupt nicht. Könnt ihr mir das bitte genauer erklären?
Was machen diese 3 Befehle?:
MAIN segment code STACK segment idata DATEN segment data
Ganz genau kann man das ohne Kenntnis des Assemblers nicht sagen. Ich denke mal, dass es den Segmenten einen Namen gibt und insbesondere ihre Reihenfolge festlegt.
Siehe oben --> Anfang.
Was hat "jmp MAIN" für einen Sinn?
Beim Einschalten springt der µC zur Adresse 0 und fängt an, den dortigen Code auszuführen. An dieser Stelle muss also Code stehen ("cseg at 0"). Da sich dann üblicherweise die Interrupttabelle anschließt, ist es ungeschickt, das eigentliche Programm (MAIN) dort abzulegen. Deshalb ist dort nur ein Befehl, der zum Hauptprogramm springt (jmp MAIN).
Der Cursor fängt immer nach "cseg at 0" an? Ich bin mit Einzelschritt durchgegangen und da wars so.
Warum schreibt man in Zeile 24 "block:"?
Das ist ein Label, damit man den Speicherbereich wiederfinden kann. Entspricht in diesem Fall der C-Definition "char block[blocksize];".
Ja was hat das label hier für einen Sinn ich sehe nirgends einen JMP-Befehl der dort hinspringt?
-
MAIN segment code
STACK segment idata
DATEN segment datadiese 3 befehle weisen den jeweiligen Namen(MAIN, STACK, DATEN) die
jeweiligen(code,idata,data) Speicherbereiche zu?Also das ganze Hauptprogramm wird im Programmspeicher gespeichert, für
den Stack wird der indirekte interne Datenspeicher zur Verfügung
gestellt und für
"DATEN"(was meint man damit?) wird der direkte interne Datenspeicher zu
Verfügung gestellt.Stimmt das
Ja aber was ist jetzt "rseg" was bedeutet das, weil cseg für Programmspeicher, dseg für datenspeicher oder?
-
Ok, mit rseg kann man die Segmente zum derzeitigen Zeitpunkt wählen.
rseg Daten block: ds blocksize
Hier wählen wir den internen Datenspeichere aus und reservieren blocksize Bytes davon.
Und block enthählt die 1. Adresse des 1. Bytes.
Korrekt?
Bei JMP MAIN.
Warum springt der genau da hin zum cseg das verstehe ich nicht. MAIN ist doch kein label?
-
assembler_anfänger schrieb:
Also programmiert wird mit dem Programm uvision3 und er uC ist wie gesagt von der der Baugruppe 8051. Am Anfang stellen wir da immer irgendeinen von Atmel oder INTEL ein. Wir haben nocht nicht wirklich gelernt was für einen GENAU wir nehmen sollen. Ich hoffe euch/dir hilft das weiter.
µVision3 ist eine sogenannte IDE (integrated development environment), also eine Oberfläche mit der Du mehrere Aufgaben in einem Rutsch erledigen kannst. Wenn z. B. auf Build Target klickst, dann ruft diese IDE den Keil-Assembler gleich mehrmals mit den vorhandenen Projekt-Dateien auf und lässt zum Schluss den Keil-Linker alle entstandenen Objekt-Dateien kombinieren. Bei Bedarf werden noch andere Programme aus \Keil\Bin aufgerufen.
Was macht cseg, rseg(STACK, DATEN, MAIN?) und ds in diesem Programm?
Es sind Hinweise an den Assembler, zu welchem Typ von Daten der nachfolgende Block gehört. Später kann ein weiteres Programm - der Linker - anhand der Hinweise die Blöcke (Segmente) sinnvoll ordnen.
Das verstehe ich überhaupt nicht. Könnt ihr mir das bitte genauer erklären?
Du musst Dich erst einmal nicht groß darum kümmern, wo später Dein Programm, Deine Daten, Deine Interrupts, Dein Stack usw. hingespeichert werden, denn das übernimmt der Assembler für Dich. Dafür musst Du ihm mitteilen: "Was jetzt kommt, sind Daten" oder "Was jetzt kommt, ist Programmcode" oder "Was jetzt kommt, ist Stack". Diesen Blöcken gibst Du am Anfang Namen wie STACK, DATEN, MAIN, SUB1, und die eigentliche Mitteilung geschieht dann mit RSEG. Du kannst die Mitteilungen auch wild mischen ("Jetzt kommen Daten, jetzt kommt Programm, jetzt wieder Daten, nochmal Programm, Daten, Programm..."). Beim Kompilieren werden dann alle dann alle Blöcke mit gleichem Namen zusammengefasst und sinnvoll geordnet, d.h. Programm in den Flash-ROM, Daten an eine bestimmte Stelle im RAM, Stack an eine andere Stelle im RAM, usw.
Was machen diese 3 Befehle?:
MAIN segment code STACK segment idata DATEN segment data
Ganz genau kann man das ohne Kenntnis des Assemblers nicht sagen. Ich denke mal, dass es den Segmenten einen Namen gibt und insbesondere ihre Reihenfolge festlegt.
Siehe oben --> Anfang.
Gut, der Keil-Linker ordnet die Segmente nicht nach den Deklarationen. Der Hauptzweck dieser drei Zeilen ist die Namensgebung für die RSEG-Befehle.
Was hat "jmp MAIN" für einen Sinn?
Beim Einschalten springt der µC zur Adresse 0 und fängt an, den dortigen Code auszuführen. An dieser Stelle muss also Code stehen ("cseg at 0"). Da sich dann üblicherweise die Interrupttabelle anschließt, ist es ungeschickt, das eigentliche Programm (MAIN) dort abzulegen. Deshalb ist dort nur ein Befehl, der zum Hauptprogramm springt (jmp MAIN).
Der Cursor fängt immer nach "cseg at 0" an? Ich bin mit Einzelschritt durchgegangen und da wars so.
Ja, das Programm fängt immer bei Adresse 0 an und "cseg at 0" assembliert den nachfolgenden Block immer an die Adresse 0.
Ja was hat das label hier für einen Sinn ich sehe nirgends einen JMP-Befehl der dort hinspringt?
Nicht nur für Sprungbefehle brauchst Du Labels, sondern auch für Ladebefehle, z.B. mov r0,#block. Labels sind nichts weiter als Namen, vergleichbar mit Ortsnamen ("Fahre mit dem VW Golf von München nach Hamburg über Frankfurt").
assembler_anfänger schrieb:
MAIN segment code
STACK segment idata
DATEN segment datadiese 3 befehle weisen den jeweiligen Namen(MAIN, STACK, DATEN) die
jeweiligen(code,idata,data) Speicherbereiche zu?Also das ganze Hauptprogramm wird im Programmspeicher gespeichert, für
den Stack wird der indirekte interne Datenspeicher zur Verfügung
gestellt und für
"DATEN"(was meint man damit?) wird der direkte interne Datenspeicher zu
Verfügung gestellt.Stimmt das
Ja. "Speicherbereich" ist vielleicht nicht ganz sauber, da µC mit ihrer Harvard-Architektur keinen zusammengehörigen Speicher haben. Du kannst das "indirekt" und "direkt" weglassen. Zwar wird der Stack meist über den Stackpointer - also indirekt - angesprochen, dass muss aber nicht so sein.
Ja aber was ist jetzt "rseg" was bedeutet das, weil cseg für Programmspeicher, dseg für datenspeicher oder?
Das 'R' in RSEG steht für "relocatable" und bedeutet, dass der Assembler/Linker entscheiden darf, welche Adresse das Segment bekommen wird. Das macht er anhand des Namens und des Typs (Keil nennt das Segment-Klasse).
assembler_anfänger schrieb:
Ok, mit rseg kann man die Segmente zum derzeitigen Zeitpunkt wählen.
rseg Daten block: ds blocksize
Hier wählen wir den internen Datenspeichere aus und reservieren blocksize Bytes davon.
Und block enthählt die 1. Adresse des 1. Bytes.
Korrekt?
Ja. Besser ist, wenn Du Dir vorstellst, dass der Assembler Zeile für Zeile übersetzt und eine Adresse vergibt. Sieht er ein Label, merkt er sich die augenblickliche Adresse. Was genau an dieser Stelle steht, ob ein Byte oder mehrere Bytes oder Programm oder eine Konstante, vergisst er sofort wieder. Er macht Dich nicht auf Fehler aufmerksam.
Bei JMP MAIN.
Warum springt der genau da hin zum cseg das verstehe ich nicht. MAIN ist doch kein label?
Richtig gesehen. Ich halte das auch für eine ungeschickte Programmierweise. Da der Keil-Assembler aber weiß, wohin er das Segment hinassembliert hat, weiß er auch, wohin der Sprung gehen soll. Wenn man aber anfängt, in größeren Projekten die Segmente wild zu mischen, dann kann es sein, dass der Programmanfang nicht mehr am Anfang von MAIN steht.
viele grüße