80c515C - Parameterübergabe

Gast #3099544
Lesenswert?

Hi Leute,

Ich verstehe die Parameterübergabe beim Infineon C515C-L nicht, kann 
mich da bitte einer aufklären. Ich habe:
1
code char text1[] = "Text-1";
2
code char *text2 = "Text-2";

Wenn ich nun diese zwei einzeln puts übergebe, so entstehen folgende 
Codes:
1. Für puts(text1):
1
MOV R3, #0xFF                
2
MOV R2, #HIGH (text1)    
3
MOV R1, #LOW (text1)      
4
LCALL _PUTS

2. Für puts(text2):
1
MOV   DPTR, #text2
2
CLR    A
3
MOVC   A, @A+DPTR            
4
MOV    R3, A
5
MOV    A, #01H
6
MOVC   A, @A+DPTR
7
MOV    R2, A
8
MOV    A, #02H
9
MOVC   A, @A+DPTR
10
MOV    R1, A
11
LCALL _PUTS

Ich versteh nicht:
1. Wieso bei "text1" R3 "0xFF" sein muss
2. Wieso bei "text2" ich insgesamt 3 Parameter (24-Byte) brauche, obwohl 
zur Adressierung nur 16-Bit notwendig sind.

Danke im Voraus!
Gast #3099562
Lesenswert?

Steffan schrieb:

> 2. Wieso bei "text2" ich insgesamt 3 Parameter (24-Byte) brauche, obwohl
> zur Adressierung nur 16-Bit notwendig sind.

Das alles sollte im Manual zum Compiler stehen. Vielleicht unter Generic 
Pointer. Denn der braucht außer dem Datenbereich noch Zusatzinfo, wo er 
liegt, im internen RAM, im Flash, oder wo auch immer.
Gast #3099621
Lesenswert?

Es heißt in der Doku nur, man müsse R3, R2 und R1 hernehmen und dass R3 
"memory type", R2 "High-Byte" und R1 "Low-Byte" wäre für "generische 
Pointer". Doch wenn wir uns mein Beispiel ansehen, so wird R3 als 
"High-Byte" bei "text2" hergenommen. Das ist zu ungenau formuliert.
Gast #3099633
Lesenswert?

Steffan schrieb:

> Wieviele von euch setzen sich so tief mit der Materie auseinander?

Ich.

Allerdings habe ich für die 8051 und 80C515 und 80C517 den 
SDCC-Compiler, nichts kommerzielles.

Da mußte ich mich mit Pointern und Übergabeparametern schon mal mit 
auseinander setzen, als ich in C eingebundene externe Assemblerfiles 
schrieb.

In einem dritten Byte wird dort der Speichertyp oder Pointer für einen 
16-bit-Wert übergeben.
Gast #3099653
Lesenswert?

Steffan schrieb:

> Ja aber was ich nicht versteh ist:
> Bei "text1" ist R3 "0xFF" und bei "text2" ist es das High-Byte.
> Was ist die Logik dahinter?

Die 0xFF bedeuten vom Wert her an sich nichts. Es ist nur eine 
Vereinbarung des Compilers.

Bei meinem SDCC-Compiler stehen da z.B. Werte wie 0x40, 0x80, 0xC0 oder 
ähnliches drin, einfach für ein Nachfolge-Programmteil, damit es den 
Speicherbereich sieht. Damit kann ich dann in einem nach folgenden 
selbst gemachten Assemblercode schauen, ob ich auf internes RAM oder 
XRAM oder externes RAM oder auf den Codebereich (z.B. ein im Flash 
abgelegtes Konstanten-Array) zu greife.
Gast #3099658
Lesenswert?

1. Das steht z. B. in der Doku nicht mit dabei (bin durch die 
source-Datei drauf gekommen)
2. Sowohl text1 als auch text2 sind mit "code" deklariert, also im 
gleichen Speicher. Wieso ist denn bei "text1" ist R3 "0xFF" und bei 
"text2" das High-Byte?
Das ist der Punkt den ich einfach nicht verstehe: Wieso ist es nicht 
einheitlich? Woher soll ich wissen, dass es so ist, wenn es nicht einmal 
in der Doku von Keil steht.
Gast #3099673
Lesenswert?

Sorry, Steffan, ich kann es dir nicht nehmen, und verstehe etwas Unmut. 
Ich habe ihn nicht produziert, und muß selbst mit den Dingen zurecht 
kommen. Das ist heute so. Nicht einfach los legen, und machen, irgendwo 
kommt ein Fall, da muß man Datenblätter und Manuals immer wieder lesen, 
lesen, lesen, und noch mal lesen.


Steffan schrieb:

> 1. Das steht z. B. in der Doku nicht mit dabei (bin durch die
> source-Datei drauf gekommen)

Kannst du 8051-Assembler? Das ist da sehr hilfreich.

> 2. Sowohl text1 als auch text2 sind mit "code" deklariert, also im
> gleichen Speicher. Wieso ist denn bei "text1" ist R3 "0xFF" und bei
> "text2" das High-Byte?

Also, da mußt du wie in Punkt 1 beschrieben, den Assemblercode mal 
schrittweise nachvollziehen, und genau verfolgen, was da im Verlauf mit 
dem Inhalt 0xFF in R3 passiert.

Welchen Compiler hast du eigentlich?
Gast #3099680
Lesenswert?

Ich hab den C51-Compiler von Keil. Wenn es irgendwo dokumentiert wär, 
wie die Parameterübergabe genau passiert, dann hätte ich hier nicht 
nachgefragt. Es heißt auf der Seite von Keil nur: R3, R2 und R1 würden 
für "generische Pointer" hergenommen werden. Das ist alles, mehr kann 
man zu dem Thema nicht finden. Ich hab nichts darüber gefunden, wo 
detailliert steht welches der Register R3 - R2 für was hergenommen wird.
Gast #3099695
Lesenswert?

Wieso, ganz einfach, weil der Code lautet:
1
MOV   DPTR, #text2
2
CLR    A
3
MOVC   A, @A+DPTR            
4
MOV    R3, A
5
MOV    A, #01H
6
MOVC   A, @A+DPTR
7
MOV    R2, A
8
MOV    A, #02H
9
MOVC   A, @A+DPTR
10
MOV    R1, A
11
LCALL _PUTS

R3 und R2 enthalten das High und Lowbyte. R1 hingegen enthält 
irgendetwas, was ich nicht verstehe. Eigentlich reichen doch R3 und R2 
aus..
Gast #3099713
Lesenswert?

Steffan schrieb:

> Es ist natürlich einfach zu sagen, dass alles im Manual steht...

Ich weiß. Manchmal mußte ich auch drei Tage im Manual (SDCC) lesen, um 
eine Sache zu begreifen, ohne mich jetzt hier als Dumpfbacke hin stellen 
zu wollen.

Nämlich meistens, wenn man nirgendwo Beispiele findet.
Gast #3099728
Lesenswert?

Das Problem ist nicht, dass ich nicht lesen kann. Es gibt Sachen, die 
stehen im Manual leider nicht ausführlich drinnen. Es gibt keine 
detaillierten Infos über das Problem das ich erläutert habe. Das einzige 
was ich machen kann ist, dass ich das ganze vom Compiler abkucke ohne zu 
verstehen, wieso das so gemacht wird..
Gast #3099743
Lesenswert?

Steffan schrieb:

> Das einzige
> was ich machen kann ist, dass ich das ganze vom Compiler abkucke ohne zu
> verstehen, wieso das so gemacht wird..

Du hast ein Problem: Du kannst keinen 8051-Assembler.

Leider wird das von C-Befürwortern auch hier im Forum immer wieder als 
nichtsnützig und unnötig deklariert. Assembler braucht keine Sau niemals 
nicht mehr. Aber in Wahrheit ist es nicht so.
Gast #3099750
Lesenswert?

Ja weil ich mir dieser Wahrheit bewusst bin geh ich dieser Wahrheit auch 
nach. Und ob dus mir glaubst oder nicht: Nur durchs Debuggen und der 
Compilerausgabe bin ich jetzt draufgekommen, dass bei "text2" ebenfalls 
"0xFF" in "R3" abgelegt wird und nicht wie vermutet das Highbyte.

Willhelm kannst du mir dann bitte eine Erklärung oder einen Link nennen, 
wo steht, wann man für "R3" (memory type) welchen Wert angeben muss? Ich 
bin immer noch auf der Suche, hab aber keine Erklärung gefunden.
Gast #3099774
Lesenswert?

Steffan schrieb:

> dass bei "text2" ebenfalls
> "0xFF" in "R3" abgelegt

Es steht auch bei beiden das Schlüsselwort code davor. Dann sind sie 
auch beide im selben Speicherbereich. Mach das code mal weg, und 
schau, was dann passiert. Die sollten dann im RAM abgelegt werden, und 
in R3 was anderes drin stehen. Als Code werden dann auch nicht mehr 
movc-Befehle generiert, sondern vielleicht mov oder movx.
Gast #3099781
Lesenswert?

Soweit war ich auch schon. Die Compilerausgabe zu lesen ist ja einfach.. 
Nur ist es schwierig zu sagen, wieso für R3 mal 0xFF bei 
"code"-Variablen und mal "0x00" bei normalen Variablen hergenommen wird. 
Nirgends ist die Codierung einsehbar. Wie soll man da vernünftig 
Assembler programmieren, wenn man bei diesem Problem nur vom Compiler 
abkucken kann?
Gast #3099790
Lesenswert?

Steffan schrieb:

> Nur ist es schwierig zu sagen, wieso für R3 mal 0xFF bei
> "code"-Variablen und mal "0x00" bei normalen Variablen hergenommen wird.

Der Compiler produziert für verschiedene Speicherbereiche sehr 
verschiedenen Assemblercode. Das liegt im 8051-Befehlssatz. Er hat 
Befehle für internes RAM, indirektes internes RAM, externes RAM, und 
Programmspeicher.

Manchmal begreift man das richtig, wenn man einen 515 mal rein in 
Assembler programmierte.
Gast #3099825
Lesenswert?

Soweit wahr ich auch schon :). Das ist mir schon klar. Nur was bedeutet 
die Codierung "0xFF", "0x00" u.s.w.. Wo kann man das nachlesen, welcher 
Code, was bedeutet? (außer vom kompilierten abzukucken)?
#3100036
Lesenswert?

Aus dem Keil Handbuch zum C51:
Seite 178 (Thema Pointer):
Memory Type    idata / data /bdata    Xdata    pdata     code
C51 Compiler       0x00                0x01     0xFE     0xFF
CX51 Compiler      0x7F                0x00     0x00     0x80

und auf Seite 164 wird Parameter Passing abgehandelt. Die Tabelle ist 
leider etwas komplex und will sich partout hier nicht guttenbergen 
lassen. In R3 wird der Speichertyp übergeben.
Gast #3100288
Lesenswert?

Nicht daß ich C auf x51 jemals gemacht hätte, aber

text1 ist ein char arry in code, hat 16addr und memtyp code, beide const
text2 ist ein in code liegender pointer auf char, ein generischer, 3byte 
pointer, denn der mentyp von char ist nicht angegeben

Also eher ein erweitertes C-Versteh-Problem.(zugegebenermaßen nicht 
trivial)

Als Compiler könnte man natürlich erkennen,daß dieser Pointer sich nie 
ändern sollte, sein Zielbereich und dessen Offset bekannt ist. 
Allerdings habe ich schon gesehen, daß x51 mit Flash auch leicht vom 
laufenden Programm aus geändert werden kann, also nicht zwingend const 
ist.
Gast #3100437
Lesenswert?

Steffan schrieb:
> kann
> mich da bitte einer aufklären

Das ist der Unterschied zwischen array und pointer. Compiliere und Linke 
das Programm einmal in der Version array und einmal mit der Version 
pointer. Vergleiche anschließend die Mapfiles in der Speicherverwendung.
Gast #3100468
Lesenswert?

C gcc schrieb:

> Also eher ein erweitertes C-Versteh-Problem

Ein wenig vielleicht auch ein 8051-Versteh-Problem.

Der 8051 ist ja in Harvard-Architektur. Er hat also zwei Adreßbereiche, 
Code und Xdata, welche quasi die gleichen Adressen haben. Auf diese 
Bereiche wird über das 16-bit-Register DPTR (Data Pointer) zugegriffen, 
aber mit separaten Befehlen. Also braucht man noch ein zusätzliches 
Unterscheidungsmerkmal, das ist eben das dritte Byte im 
Parameter-Passing. Außerdem hat der 8051 auch noch einen Idata-Bereich, 
ebenfalls mit den gleichen Adressen. Dort wird aber nur ein 8-bit-Wert 
für den 8-bit-Pointer gebraucht, und das zweite Byte kann leer bleiben.

Keil unterstützt auch noch Banking von Code und Xdata, so daß man den 
8051 (auch 80C515 und 80C517 und viele andere Derivate) mit einem 
Vielfachen des normalen maximalen Speicherausbaues von 64k gestalten 
kann. Ursprünglich war das vom Chiphersteller mal gar nicht vorgesehen, 
weil man glaubte, daß 64k für alle Zeiten reichen würde. Da wird es auch 
wieder etwas komplizierter, es werden dort anderweitig noch freie 
I/O-Pins für die Speicheradressierung mit heran gezogen, auf die man 
dann für andere I/O-Zwecke verzichten muß. Ich brauchte das selbst nie, 
habe nur mal ein wenig in diese Techniken geschnuppert. Man kann sich 
das Banking aber auch mit jedem anderen Compiler oder Assembler selbst 
gestalten, es ist nur etwas aufwändig. In einem alten Faxgerät fand ich 
einmal tatsächlich einen 8051 mit einem Megabyte-EPROM, dort wurde es 
also angewandt. Zu sehen waren im EPROM tatsächlich in 64k-Abständen die 
Interruptvektoren. Dann muß das EPROM in jeder 64k-Bank auch ein 
Bankumschaltungsprogramm haben. Man muß da bei der Programmierung also 
Vorsicht walten lassen. Da sind moderne Controller heute bequemer. Im 
Prinzip funktioniert diese Bankumschaltung etwa wie die Überschreitung 
einer Landesgrenze mit einer älteren Allstrom-Eisenbahnlok.

Aber ich schlug dem TO ja bereits gestern schon vor, die beiden 
Speicherreservierungen nicht im Code anzulegen, sondern in Data bzw. 
Xdata. Dann wird er im R3 nicht den Wert 0xFF finden, sondern 0xFE, und 
auch anderen compilierten Code.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren