Hallo zusammen, ich hätte da mal einige Frage. Habe hier ein Programm mit dem ich mich auseinender setzen muss jedoch verstehe ich nicht was genau das codesegment ist und für was dieser in dem Programm genutzt wird. CSEG AT 0 sagt mir auch nicht viel und was macht der Befehl Org und warum wird die hexazahl 50h gewählt? Danke im vorraus ;***************************** ; Segmentierung von Speicher * ;***************************** stack_seg SEGMENT IDATA ;Deklaration Stack segment indirekt adressierbarer, internes RAM zb Stack code_seg SEGMENT CODE ;Deklaration Code Segment, Programmspeicher ROM ;***************************** ;* Stack-Initialisierung ***** ;***************************** RSEG stack_seg ; RAM-Speicher wird ausgewählt unser Stack init: DS 10 ; 10 Byte Stack wird reserviert, damit Daten gesichert werden nach LIFO CSEG AT 0 ; Anfangsadresse für Progstart ist 0, Absolutes Codesegment für Programmstart bei 0 JMP main org 0Bh ; Adresse für die ISR von Timer0 festlegen der nachfolgende Code wird ab Adresse 0B im Programmspeicher abgelegt JMP timer_0 ; Läuft Timer 0 ab, verzweigt der Controller zur Adresse 0Bh zur Interruptbehandlungsroutine org 50h ; Anfangsadresse/Einsprungstelle für die BCD-Tabelle wird festgelegt JMP bcd ; Tabelle an Adresse 50h
die Hinweise/Antworten stehen alle schon in dem gut dokumentierten Listing !
Da steht einiges über 8051, hier erstmal der Grund für die 50: http://www.self8051.de/Speicherorganisation_des_8051_Mikrocontroller,18091.html
Hey danke für die Antwort. also ist die 0Bh vordefiniert in dieser Tabelle die 50h habe ich jedoch nicht gefunden und kann mir vil einer genau erklären was genau cseg macht. Ich habe es so verstenden dass nachdem cseg immer das Programm beginnt ist das so richtig?
Es gibt CSEG = CODE Segment = hier steht Programmcode, in Stein gemeisselt. Dann DSEG = DATEN Segment = hier kommen Daten hin, hier kann der Prozessor auch schreiben. Bei anderen Prozessoren findest du noch SSEG = Stack, ESEG = Extra usw. Die Segment Angaben helfen dem Linker/Locater, zueinander passende Programmteile aus verschiedenen Modulen zu verheiraten.
Und was bedeutet das at bei cseg Und ist es mit Absicht dass direkt drunter jmp Main steht ? Warum steht da org 50h und direkt dahinter jmp bcd hat das einen Zusammenhang ,
Jürgi schrieb: > Und was bedeutet das at bei cseg At ist der Befehl, das Segment für Code ab der genannten Adresse anzulegen. Org heisst, das folgende Programm soll ab der genannten Adresse gespeichert werden. Da die meisten Prozessoren nach Reset an Adresse 0 starten, muss daher das CSEG bei 0 beginnen und zwar mit dem Befehl, der per ORG an der Adresse 0 assembliert wird. Führt z.B. ein Interrupt laut Manual an die Adresse 00xy, so muss die Interruptroutine logischerweise mit ORG 00xy vor dem ersten Befehl programmiert werden und das innerhalb CSEG. Dann befördert der Linker die Routine in den Programmspeicher an der Adresse 00xy. Natürlich dürfen sich die Programme nicht ins Gehege kommen, der Code, der ab 0 ausgeführt wird, darf z.B. nur bis vor die Adresse xy reichen, sonst meldet das Assemblerprogramm einen Fehler. Gruss Reinhard
Es wurde ja gesagt dass die ersten 50 Adressen vordefiniert sind heißt das von 0 bis 49h sind die vordefinierten und die 50h ist die erste freie Adresse ?
JÜRGI schrieb: > was sind jedoch die 50h? Dort hat jemand den Teil bcd hin verlegt, weil der das praktikabel fand. 050h liegt kurz hinter den Interruptvektoren. Denn der 8051 hat mehrere Interruptvektoren, nicht nur den 0Bh, die bis etwa in die Gegend um 40h herum reichen. Die überspringt man, und läßt sie reserviert, wenn man sonst genug Codespeicher hat. Man könnte die nicht benutzten Interruptvektoren jedoch auch als normalen Codebereich verwenden, bspw. wenn der Speicher mal voll wird, und man dringend noch ein paar Bytes irgendwo zusammen kratzen muß. Es kann sein, daß der Linker main noch vor bcd legt, oder eben dahinter, je nach dem, wie groß beide Codesegmente sind.
Danke , eine letzte frage habe ich noch . Warum werden org und jmp zusammen verwendet heißt es dass wenn ein interrupt kommt soll er an diese Adresse springen . Aber was heißt für die bcd Tabelle jmp bcd und org ?
Org = Origin legt fest, wo im aktuellen Segment der nun folgende Code liegen soll. Jeder Interrupt hat einen speziellen Vektor, fängt an einer vorgegebenen Adresse an. Diese Vektoren liegen i.A. sehr eng beieinander, so dass zwischen zwei Vektoren nicht genug Platz ist für den Code, der im Interrupt ausgeführt werden soll. Also ist der erste Befehl meist ein Sprungbefehl zu der ersten "echten" Instruktion des Interrupts.
Jürgi schrieb: > Warum werden org und jmp > zusammen verwendet Muss ja nicht sein. Aber die Adressen, an die der Prozessor durch einen Interrupt springt, folgen meist dicht aufeinander, daher muss ein längeres Programm zur IRQ-Bearbeitung irgendwo anders stehen, und da führt dann eben ein JMP hin (bzw. LJMP). Genausogut kann aber an der IRQ-Service-Adresse ein RETI stehen, wenn dieser spezielle Interrupt keine Bearbeitung braucht. Die 50H, nach denen du schon mehrfach gefragt hast, sind auch nicht in Stein gemeisselt, sondern von der Hardware abhängig, je nach Zahl der Interruptquellen, beim 80535 gibt es z.B. eine IRQ 6BH. Da wäre der nächste freie Speicherplatz also nicht 50H, sondern 70H. Ich habe immer gleich 100H als ersten freien Programmspeicher gesetzt. Gruss Reinhard
Danke Reinhardt , Wenn ein interrupt kommt wird das Programm also unterbrochen und springt in die interrupt Routine die an der vordefinierten Adresse 0bh steht . Die bcd Tabelle wurde vom Nutzer an die Adresse 50h gespeichert. Habe ich das richtig verstanden ?
JÜRGI schrieb: > danke für die antwort, was sind jedoch die 50h? Du scheinst ein bissel schwer in die Gänge zu kommen, gelle? also: Es gibt unterschiedliche Rechnerarchitekturen, gelle? Bei manchen sind Daten (sowohl konstante als auch variable) und der Befehlscode im gleichen Adreßraum angeordnet. Bei anderen jedoch nicht. Es gibt sogar Architekturen, wo der Code, die variablen Daten und die In- und Out- Verbindungen zur Außenwelt in jeweils unterschiedlichen Adreßräumen angeordnet sind. Hier haben wir es nur mit 2 Adreßräumen zu tun: dem Code im ROM/EPROM/FLASHROM und den variablen Daten im RAM. Jeder Adreßraum hat seine Adressen und was im RAM auf Adresse 50h steht, ist dem ROM auf seiner Adresse 50h völlig wurscht. Also gibt es im Assembler sogenannte Pseudobefehle oder Organisationsanweisungen, die keinem Maschinencode entsprechen, sondern dem Assembler sagen, was der Programmierer in den nächsten Zeilen eigentlich meint. Oft trifft man sowas an: SEG CODE oder SEG DATA was dem Assembler sagt, daß alles, was danach kommt, in den Code (bzw. ROM) kommt oder eben in den Datenbereich, also den RAM. Klar bisher? Nun will man als Assemblerprogrammierer ja gelegentlich irgendetwas an genau eine bestimmte Stelle im jeweiligen Segment plazieren. Dazu dient dann ORG 50h womit alles was man danach schreibt, ab der Adresse 50h plaziert wird. Zumeist ist es so, daß der Assembler aus purer Menschenfreundlichkeit bei seinem Start die ORG-Zähler für alle Segmente, die es so geben mag, auf 0 setzt. Deshalb landet der allererste Befehl nach dem allerersten SEG CODE auf Null, aber man sollte sich darauf nicht verlassen und lieber selbst nach einer Segmentanweisung eine ORG anweisung schreiben, WENN (!!!) man das Folgende auf einer bestimmten Adresse haben will. Es geht nämlich auch verschachtelt: SEG RAM ORG 15 MyLovelyByte: DS 1 ;reservierung eines Bytes im RAM SEG Code ORG 0 JMP MyStartup Manifest: DEFB "My lovely Program",0 SEG RAM MyFollowingByte: DS 1 ; noch ein Byte resevieren SEG Code MyStartup: .. hier nun Befehle nach deinem Gusto.. Dabei landen MyLovelyByte auf Adresse 15 im RAM, MyFollowingByte auf Adresse 16 im RAM und MyStartup landet direkt hinter dem Manifest, also hinter dessen abschließendem Nullbyte. hast du's nun? W.S.
Hallo, zum tieferen Verständnis: bei jedem Prozessor kann man jeden Platz im Programmspeicher per JMP/LJMP erreichen (sonst bräuchte man den Speicher ja nicht einbauen oder anschliessen), also kann ein bestimmter Programmcode an jeder beliebigen Adresse stehen, mit einigen Ausnahmen: Nach einem Reset wird an eine bestimmte Stelle gesprungen, weit verbreitet dafür ist die Adresse 0 - das nennt man dann Reset-Vektor. Der muss fest sein, denn von irgendetwas muss man ausgehen können, sozusagen der Fixpunkt im Code-Universum. Also ist das für den Programmierer der Punkt an dem sein Programm startet. Bei den meisten heutigen Prozessoren sind auch die Interruptvektoren festgelegt, d.h. beim Empfang eines Bytes im UART springt der Prozessor an eine bestimmte Adresse, die man aus dem Manual erfährt. Also muss der Code zur Bearbeitung des Interrupts an dieser Adresse anfangen, aber weil das meistens eine ganze Tabelle von Adressen ist, reicht dort der Platz nicht für viel mehr als einen Sprung dahin, wo die Interruptroutine wirklich steht. Früher waren die Interruptadressen oft noch programmierbar (Z80), aber das ändert prinzipiell nichts und bringt kaum Vorteile (dafür viele Fehlermöglichkeiten), deshalb sind sie in moderneren Architekturen einfach fix. Der Linker schafft Codeteile dahin, wo noch keine sind, meistens in der Reihenfolge wie sie im Makefile aufgeführt sind, daher muss man im bei solchen fest addressierten Codeabschnitten mitteilen, dass er sie gefälligst an einer bestimmten Adresse unterzubringen hat - das genau ist die ORG-Anweisung. Gruss Reinhard
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.