Hallo Leute! Ich habe hier leider nichts technisches in diesem Topic, aber dennoch gehört es zu uCs, daher hoffe ich, mir kann hier jemand helfen. Ich versuche zu verstehen, was eigentlich genau im uC passiert, wenn der Quelltext da reingeflasht wird. Gibt es irgendwo im Netz Literatur dazu, wie die Umsetzung von dem geschriebenem C über den Compiler in Maschinensprache und dann in den Flash des uCs erfolgt? Also was das Programm letztendlich im Controller bewirkt? So richtig auf Hardware-Ebene meine ich damit. Der Maschinencode bewirkt ja im Endeffekt nur das setzen oder löschen von irgendwelchen Nullen und Einsen, daber ich habe im Netz bisher nichts brauchbares dazu gefunden. Sorry, evtl. klingt das grad etwas seltsam für manche, aber mir fehlt da einfach die Vorstellungskraft, was aus meinem C-Programm eigentlich wird. Gruß
Daniel schrieb: > Ich versuche zu verstehen, was eigentlich genau im uC passiert, wenn der > Quelltext da reingeflasht wird. es wird kein Quelltext reingeflasht, sondern Maschinencode. Villeicht ist das dein Verständnisproblem.
Wegstaben Verbuchsler schrieb: > es wird kein Quelltext reingeflasht, sondern Maschinencode. Villeicht > ist das dein Verständnisproblem. Ja, OK, dumm ausgedrückt, aber das habe ich hier ja auch geschrieben: Daniel schrieb: > Umsetzung von dem > geschriebenem C über den Compiler in Maschinensprache und dann in den > Flash des uCs
Die Umsetzung des C Codes in den Maschinen Code beding erst mal ein Verstaendnis des Maschinen Codes, nachdem man den C Code verstanden hat. Die Maschinensprache ist im ASM/Instruction Manual des betreffenden Controllers zu finden. Ja es geht um Bits setzten und loeschen. So etwa. Also einfach mal das Instruction Manual des Controllers runterziehen.
Grob gesagt passiert folgendes: Compiler und Linker übersetzen Deinen C-Code in eine vom uC verständliche Sprache. Wo der Unterscied zwischen Compiler und Linker ist,habe ich einmal versucht im folgenden Video zu erklären: http://et-tutorials.de/938/was-machen-compiler-und-linker/ Der Loader kopiert den erzeugten maschinen,lesbaren Code in den Speicher des uC. Nach dem Start des uC zeigt der Befehlszeiger des uC immer auf eine genau definierte Stelle. Der Befehl, der an dieser Stelle abgelegt ist, wird also als erstes ausgeführt. Der Loader muss also Dein Programm so in den Speicehr des uC kopieren, dass der erste Befehl genau in dieser Speicherstelle steht. Der uC holt also nach dem Start den ersten Befehl aus dieser Speicherstelle und erkennt, was zu tun ist. Ob also noch weitere Daten geladen werden sollen, o.ä., führt dann diesen Befehl aus, setzt der Befehlzeiger auf die nächste Speicherstelle. liest den Inhalt dieser Speicherstelle (in der ja der nächste anzuarbeitende Befehl steht) aus , usw. Ich hoffe, das Prinzip ist deutlich geworden.
Hi
>Ja es geht um Bits setzten und loeschen.
Das wäre etwas wenig.
MfG Spess
vielleicht kann man das ganze umgekehrt aufrollen? sich erstmal mit FPGA & Co beschäftigen bis hin zu softcores und dann erst Compiler und Programmiersprachen?
> >Ja es geht um Bits setzten und loeschen. > Das wäre etwas wenig. Wieso? Das würde ich schon so sehen. Alle Befehle setzen und Löschen letztlich irgendwelche Bits, je nach Befehl halt nach anderen Regeln.
Dan gibt es noch Spruenge, Zaehler, Register, eine ALU, Stack, usw.
Hi Wenn du dieser Welt näher kommen möchtest, schreib ein paar Programme in Assembler. Klar, Assembler versteht der Controller auch nicht, den die Befehlsdecoder reagieren nur auf Binärcodes, dennoch kommst du dem Verständnis etwas näher. Dann schau mal in die Datenblätter. Da gibt es Skizzen, die innere Strukturen verdeutlichen. Es ist wahrhaftig kein Hexenwerk, allerdings sehr komplex. Sagen wir, von elektrischen Schaltkreis bis zum µC ist es ein Weg von den Grundrechenarten bis hin zur höheren Mathematik... Letztlich sind auch in der höheren Mathe die Grundrechenarten enthalten. Gruß oldmax
Ich gebe mal ein Beispiel einer if-Abfrage: if(variable == 0){... variable sei eine CHAR-Variable, also eine 1 Byte-Variable. Der Inhalt der Variable ist im Ram in einem Register. Der Compiler (für PIC-µCs) würde daraus sowas in der Art machen können: (1) movf %adresse_im_ram_%,w (2) btfss STATUS_REG, Z (3) goto endif (4) ... (x) endif: (1) Hier kopiert der Prozessor den Inhalt der Speicherzelle in das Work-Register. Dabei wird überprüft, ob das Ergebnis, sprich die Kopierte Zahl und somit der Inhalt der variablen 0 ist. Wenn ja, wird das sogenannte Zero-Flag gesetzt. (2) Hier wird das Zeroflag geprüft das sich im STATUS_REG-Register befindet. Wenn das der Fall ist, wird der Folgende Befehl übersprungen. Wenn nicht, dann nicht. (3) Den Befehl ruft er nur auf, wenn das Zero-Flag nicht gesetzt ist, also wenn die Kopierte Zahl nicht Null ist. Er springt also zu einer Sprungmarke (x), die nach dem compiliertem {}Block des Ifs kommt. (4) Hier springt er hin, wenn das Zero-Flag gesetzt ist. Da kommt nun der compilierte Inhalt vom {}Block des Ifs. Das ist der erzeugte Assemblercode. Aus diesem wird dann der Maschinencode generiert, der Quasi genau das gleiche wie Assembler ist, nur das alles Hexadezimale zahlen sind. Die Adresse der Variable oder des Status-Registers im RAM ist eine Zahl, die Befehle sind auch zahlen usw. Es wird also gesehen, dass Beispielsweise für den Befehl "movf %adresse_0x40%,w" folgendes generiert wird: 00 1000 0100 0000. Wieso? "00 1000" ist die Zahl für das MOVF. Das bit danach, also die "0" steht für das Ziel, in diesem Fall das W-Register. Das "100 0000" steht für die 0x40, also die Adresse im RAM. Und mit diesem 00 1000 0100 0000 macht die CPU dann das, was er soll. Bei MOVF kopiert er wie geschrieben den Inhalt einer Adresse, mit btfss prüft er ein Bit eines Registers. Wenn es 1 ist, führt er statt dem nächsten befehl ein NOP aus, also ein "No operation", also nichts. Er überspringt also den nachstehenden Befehl. Wenn nicht, führt er das goto aus. Jeder Befehl steht hintereinander im Programmspeicher. Und jeder Speicher hat eine Adresse, die mit dem PC(Program Counter) bestimmt wird. Die Sprungmarken sind somit nichts anderes, als das Representieren einer Adresse im Programmspiecher. Angenommen im obenstehenden Code ist die Sprungmarke "endif" in dem Register des Programmspeichers 0x277, dann wäre der goto-Befehl also 10 1010 0111 0111. "10 1" Für das GOTO und das "010 0111 0111" für die Zeiladresse. Diese wird dann in den Programcounter geschrieben und er springt zu der Adresse. http://ww1.microchip.com/downloads/en/devicedoc/35007b.pdf Wenn du mal gucken willst, ab Seite 35 (PDF-Seite 37), Kapitel 7, steht wie es Funktioniert, welche Befehle es gibt und auch welche Flags die Befehle beeinflussen können. Es gibt zum Beispiel auch das Carry-Flag, das überprüft, ob durch eine z.b. Addition eine Zahl größer als 255 wurde und somit mit 8 bit nicht mehr gespeichert werden kann. Im Allgemeinen sind Datenblätter Hilfreich. Hier, beim PIC16F84A ist es noch recht übersichtlich, da es ein sehr alter PIC ist. Zum Grundlagen lernen schon nicht schlecht, ansonsten ist es ein echtes sch*** Ding ;) Teuer, lahm und hat kaum Peripherie usw.
Hey Leute vielen Dank schonmal für eure teilweise sehr ausführlichen Erklärungen!!!
fand ich jetzt auch sehr erhellend, vielen dank! Ciao, Tim
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.