Forum: Mikrocontroller und Digitale Elektronik 8051 intel Microcontroller


von jürgi (Gast)


Lesenswert?

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

von antwortbär (Gast)


Lesenswert?

die Hinweise/Antworten stehen alle schon in dem gut dokumentierten 
Listing !

von bko (Gast)


Lesenswert?

Da steht einiges über 8051, hier erstmal der Grund für die 50:
http://www.self8051.de/Speicherorganisation_des_8051_Mikrocontroller,18091.html

von jürgi (Gast)


Lesenswert?

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?

von Georg G. (df2au)


Lesenswert?

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.

von Jürgi (Gast)


Lesenswert?

Ok was verstehe ich nun unter der 50h ?

von Jürgi (Gast)


Lesenswert?

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 ,

von Reinhard Kern (Gast)


Lesenswert?

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

von JÜRGI (Gast)


Lesenswert?

danke für die antwort, was sind jedoch die 50h?

von Jürgi (Gast)


Lesenswert?

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 ?

von Wilhelm F. (Gast)


Lesenswert?

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.

von Jürgi (Gast)


Lesenswert?

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 ?

von Georg G. (df2au)


Lesenswert?

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.

von Reinhard Kern (Gast)


Lesenswert?

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

von Jürgi (Gast)


Lesenswert?

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 ?

von W.S. (Gast)


Lesenswert?

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.

von Reinhard Kern (Gast)


Lesenswert?

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

von JÜRGI (Gast)


Lesenswert?

Danke für alles

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.