Forum: Mikrocontroller und Digitale Elektronik 80c515C - Parameterübergabe


von Steffan (Gast)


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!

von Wilhelm F. (Gast)


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.

von Steffan (Gast)


Lesenswert?

Wieviele von euch setzen sich so tief mit der Materie auseinander? Oder 
würdet ihr bei diesem Modell eher in C programmieren?

von Steffan (Gast)


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.

von Wilhelm F. (Gast)


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.

von Wilhelm F. (Gast)


Lesenswert?

Steffan schrieb:

> und dass R3
> "memory type"

Na also.

von Steffan (Gast)


Lesenswert?

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?

von Wilhelm F. (Gast)


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.

von Steffan (Gast)


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.

von Wilhelm F. (Gast)


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?

von Steffan (Gast)


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.

von Steffan (Gast)


Lesenswert?

Hier steht z. B., dass R3 immer das "mem type" ist hergenommen wird es 
bei "text2" hingegen als "High-Byte"..

von Steffan (Gast)


Lesenswert?


von Dieter W. (dds5)


Lesenswert?

Steffan schrieb:
> Hier steht z. B., dass R3 immer das "mem type" ist hergenommen wird es
> bei "text2" hingegen als "High-Byte"..

Warum soll es das high Byte sein?

Es wird wahrscheinlich genau wie bei text1 "mem type" sein, nur steht es 
halt unmittelbar vor der 16 Bit Adresse.

von Wilhelm F. (Gast)


Lesenswert?

Dieter Werner schrieb:

> Es wird wahrscheinlich genau wie bei text1 "mem type" sein, nur steht es
> halt unmittelbar vor der 16 Bit Adresse.

Mannnnnn!!! Das steht doch ausgerechnet bei Keil bestimmt alles im 
Manual!!!

von Steffan (Gast)


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..

von Steffan (Gast)


Lesenswert?

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

von Wilhelm F. (Gast)


Lesenswert?

Definier deine Speicherreservierungen mal probehalber ohne die Anweisung 
"code". Und schau, was der Compiler dann macht.

von Wilhelm F. (Gast)


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.

von Steffan (Gast)


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..

von Wilhelm F. (Gast)


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.

von Steffan (Gast)


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.

von Steffan (Gast)


Lesenswert?

Und es sieht so aus, als würde FFh (R3) für "MOV R7, A" stehen. D. h. R3 
beinhaltet einen Opcode. Es wird immer grußliger.. :)

von Wilhelm F. (Gast)


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.

von Steffan (Gast)


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?

von Wilhelm F. (Gast)


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.

von Steffan (Gast)


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)?

von Peter D. (peda)


Lesenswert?

Wo ist das Problem?

Puts braucht in R3 den Memory-Typ und in R2,1 die Adresse.

Text1 ist ein String, da kann er die Register direkt laden.
Text2 ist aber ein Pointer, also muß er diesen Pointer auslesen und nach 
R3,2,1 laden.

Ist alles korrekt.

von Georg G. (df2au)


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.

von Steffan (Gast)


Lesenswert?

Hey Super!

In welchem Manual steht das ?

gruß

von Georg G. (df2au)


Lesenswert?

Steffan schrieb:
> In welchem Manual steht das ?

Ist beim KEIL Paket dabei, auch in der freien Version. C51.PDF nennt 
sich das File, im Verzeichnis ~/C51/HLP, gut 1.3MB

von Steffan (Gast)


Lesenswert?

Es ist schon lustig, dass man das manual auf der Seite von Keil nicht 
direkt findet, sondern erst auf einer externen Seite..

von Zahnfee (Gast)


Lesenswert?

> Ist beim KEIL Paket dabei, auch in der freien Version.

Kann ich gar nicht glaube. Wo gibt es eine freie Keilversion?

von Georg G. (df2au)


Lesenswert?

Bei Keil, wo sonst? Die schicken dir sogar eine CD, falls du Probleme im 
Download hast. Das sind auch sonst sehr nette Leute, wenn man Fragen 
hat.

von Zahnfee (Gast)


Lesenswert?

Georg G. schrieb:

> Bei Keil, wo sonst? Die schicken dir sogar eine CD, falls du Probleme im
> Download hast. Das sind auch sonst sehr nette Leute, wenn man Fragen
> hat.

Das ist doch Unsinn. Die verkaufen Ihre Entwicklungsumgebungen für gutes 
Geld. Frei Version: Quatschkopf.

von Georg G. (df2au)


Lesenswert?

Wenn du irgendwann mal erwachsen wirst, lernst du vielleicht dazu:

https://www.keil.com/c51/demo/eval/c51.htm

Die maximale Größe des fertigen Codes ist begrenzt, reicht aber für 
viele Hobbyprojekte aus. Und die Doku ist vollständig und gut.

von C gcc (Gast)


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.

von array is nicht pointer (Gast)


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.

von Wilhelm F. (Gast)


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.

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.