Hallo Xin,
Xin hat geschrieben:Vielleicht können wir in Zusammenarbeit mit Gerd da ein Kurztutorial draus machen, wie man aus verschiedenen Programmiersprachen ein Programm zusammenlinken kann?!
Ich schreibe
kein kombiniertes Programm, also kein C- und Assemblerprogramm, sondern ein reines C-Programm.
Grund dafür ist, dass ich den Pythagoras bemühen muss um meinen Kurs zu bestimmen.
Ich brauche die Funktionen cos(x) und arctan(x) dafür, das ist der einzige Grund für mich im Moment um C zu lernen bzw. damit zu Programmieren. Mir haben bislang für meine Projekte immer Assembler und zum Austesten bzw. zum Steuern meiner Entwicklungen PureBasic gereicht, Purebasic auch nur soweit wie ich es für meine Anwendungen brauchte.
Meine Frage zielte bislang immmer darauf hin, ob das Ergenis meiner Rechenfunktion, bislang ja nur die Subtraktion, fest im RAM erhalten bleibt und ob das so mit den Werten als globale Variablen funktioniert.
Die Frage ist bislang mir noch nicht verständlich beantwortet worden.
Ob man die Variable
double zu Testzwecken auf ein Port ausgeben kann welches nur 8-Bit-Breite hat ist wohl eher unwahrscheinlich.
Diese Lösung fällt folglich komplett flach ebenso die 16-Bit-Register im Microcontroller, bleibt nur noch als Lösung das RAM übrig.
Ich rede zwar hier von Assembler, meine aber damit
nicht den Source-Code!
Um das mal etwas klarer darzustellen hier mal ein Auszug aus dem übersetzten Teil des vorhandenen C-Source-Code welches nur aus der einer einzigen Subtraktion in
main besteht:
Das Ganze Progrämmchen hat eine Länge von über 2kB, in Assembler würden es keine 100 Byte sein!
Code: Alles auswählen
000000ae <main>:
double B_Unterschied = 0; // Breigengradunterschied
int main (void)
{
B_Unterschied = A_Breite - Z_Breite; // Unterschied Breitengrad berechnen
ae: 60 91 14 01 lds r22, 0x0114
b2: 70 91 15 01 lds r23, 0x0115
b6: 80 91 16 01 lds r24, 0x0116
ba: 90 91 17 01 lds r25, 0x0117
be: 20 91 18 01 lds r18, 0x0118
c2: 30 91 19 01 lds r19, 0x0119
c6: 40 91 1a 01 lds r20, 0x011A
ca: 50 91 1b 01 lds r21, 0x011B
ce: 0e 94 be 01 call 0x37c ; 0x37c <__subsf3>
d2: 60 93 44 01 sts 0x0144, r22
d6: 70 93 45 01 sts 0x0145, r23
da: 80 93 46 01 sts 0x0146, r24
de: 90 93 47 01 sts 0x0147, r25
e2: ff cf rjmp .-2 ; 0xe2 <main+0x34>
Rechter Teil das Assemblerlisting und links der Hex-Code bzw. das ist der Maschinencode.
Diese Subtraktion
B_Unterschied = A_Breite - Z_Breite;
lädt aus dem RAM ab 0x0114 per
lds (Speicher direkt auslesen) ihre Rechenwerte vom RAM in entsprechende Register,
springt dann per
call in eine Subtraktionsroutine,
liefert dann über die Register r22-25 per sts (speicher direkt ins RAM) einen Wert ab, vermutlich bzw. muss so sein, das Ergebnis der Subtraktion vom Typ double.
Auf diese Speicherstellen habe ich per AVR-Studio direkten Zugriff und kann die Werte während der Simulation auslesen.
Es steht nichts lesbares drin ...wenigstens nicht für mich im Moment, auch kein entsprechender Binärcode, ASCII schon garnicht.
Ich weiss nicht wie im Maschinencode eine Variable double abgespeichert bzw. aufgelöst wird.
Meine einzige Frage zum meinem C-Code ist nun:
Werden für die Rechenoperation die globalen Variablen mit ihren Werten verwendet, so wie ich sie deklariert habe?
Wird das Ergebnis auch in der entsprechenden globalen Variable gespeichert?
Bleiben die Variablen A_Breite und Z_Breite mit ihren Werten erhalten?
Ich habe zwar 2 Bücher für C hier, aber über solche Probleme lassen sich keines der Bücher aus.
Auch nicht das Buch
Microcomputertechnik mit Controllern der Atmel AVR-RISC-Famlie - Programmierung in Assembler und C-
In dem Buch wird auch fast nur über Registeranwendungen geschrieben, die mich aber für dieses Problem nicht interessieren sondern reine Mathematik in C.
prinf funktioniert bei mir nicht (schon probiert), also kann ich es nicht auf dem Bildschirm ausgeben und kontrollieren.
Register und Ports fallen auch flach, denn die errechnete Zahl kann ja ewig lang sein.
In meinem Beispiel benutzt der Compiler laut Assemblerlisting wohl 4 Byte für je einen double-Wert mit Komma.
Gruss
Gerd