Hallo Leute ich habe mich vor kurzem angefagen mit Assembler zu beschäftigen. Ich wollte einen PIC16F628 programmieren. Habe ein Projekt von Microchip downgeloadet und versuche nachzuvollziehen was und wie die dort programmiert haben und bin gleich auf was gestoßen. Finde leider nichts aussagekräftiges was diese Zeilen zu bedeuten haben: STARTUP CODE INTVCT CODE MAIN_SETUP CODE EE_DATA CODE 0x2100 Zwischen den Zeilen ist Quelltext, den ich einigermaßen verstehe. Meine Vermutung ist, dass z.B. STARTUP CODE anstelle von org 0 steht und INTVCT CODE anstelle von org 4 den rest keine Ahnung. Würde mich freuen wenn mir jemand das erläutern könnte. MfG Iwan
hat denn niemand sowas schon mal im Quelltext gesehen?
Gast
#1451411
Hallo, so etwas habe ich noch nie gesehen
Gast
#1451420
stell doch mal das File hier rein.
hier nochmal das mainFile aus dem Projekt. Ich vermute dass es auch irgendwas mit mplab zutun hat. Danke schon mal voraus für die Mühe.
Gast
#1451538
hi das sieht nach Defines aus wie sie normalerweise in der pic16f628.inc stehen also im linker script
aha ich habe in die pic16f628.inc reingeguckt, finde aber nichts vergelichbares oder bin ich zu dämlich :-) wo könnte man nachschauen was das bedeutet?
Gast
#1451554
Startup Definiert den Start Vector wo der Mikrocontroller beim Einschalten reinspringt. INTVCT CODE: Definiert den Interruptvektor Main Setup Code: Ist der Bereich wo das Hauptprogramm steht. EE_Data Code 0x2100: Gibt im EEPROM die gesamte Menge aller Bytes an bzw. diese welche Reserviert werden. Ich kenne mich mit PICs 0 aus da ich Atmels µcs Programmiere aber ich denke das wird so passen. Assembler ist Assembler.
danke dir TrippleX kannst du auch verraten wo du dieses Wissen her hast, ich würde gerne selber was darüber lesen. Ich glaube auch, dass das so ist. Nur habe ich beispielsweise bei sprut.de gesehen, dass man direkt Adressen eingibt wo jetzt nun z.B. der interrupt hinspring. Das wäre dann die Anweisung: org 4
Gast
#1451854
ich habe mir die Dateien, die zu deinem Projekt gehören, näher angeschaut. Schau doch mal in das Linkescrip (16f628.lkr) an. Da findest du deine Vektoren. Wenn du mehr darüber wissen willst, dann schau dir doch den GCC-Assembler bzw. Linker an. Ich habe mal einen Atmel ARM mit GCC programmiert. Da hat mir GCC-Assembler/Linker-Doku weiter geholfen, die Funktionsweise/Zusammenspiel der beiden zu verstehen, vor allem wenn du den Startup-Code für deinen µC schreiben musst.
vielen dank für die Antwort blicke noch nicht ganz durch aber werde mir die Sachen in den nächsten Tagen mal genauer ansehen.
Gast
#1452585
schau hier rein
jo dankeschön werde ich tun, 300 Seiten auf englisch, wie ich das liebe :-)
so habe mir die 16f628.lkr genauer angeguckt und finde dort beispielsweise den Eintrag: MAIN_SETUP niergends, es sind noch mehr einträge im Quelltext der .asm Dateien wo dahinter immer CODE steht die aber nicht in 16f628.lkr vorhanden sind. Aus dem Projekt lässt sich dennoch ohne errors ein HEX-File erstellen????? Ich versteh garnichts mehr.
Gast
#1454402
Ich glaube du versuchst auf einen Schlag zu viel zu schlucken und
verschluckst dich natürlich dabei. Hast du den Zusammenhang zwischen
Assembler und Linker verstanden bzw. was das Linker-Skript für eine
Funktion hat und wie es aufgebaut ist? Verstehts du die
Assembler-Syntax, weißst du, was Sections sind?
Mein Ratschag, fang mit einem kleinen Programm an, dass du verstehts,
was es macht. Arbeite dich langsam nach vorne, kannst dir nebenbei auch
das Map-File dann anschauen.
Um mal auf deine Frage einzugehen, schau dir mal das PDF-File auf Seite
57 an. Da steht folgendes:
PGM CODE ;This is the beginning of the
;code section named PGM. It is
;a relocatable code section
;since no absolute address is
;given along with directive CODE.
Dein MAIN_SETUP ist nix anderes wie ein Code-Segment(Section), wo es
genau beginnt, das wird dann vom Linker erledigt. Wenn du dir das
dali.map anschaust, findest du folgende Zeilen:
Section Type Address Location Size(Bytes)
--------- --------- --------- --------- ---------
STARTUP code 0x000000 program 0x000002
INTVCT code 0x000004 program 0x00000c
.cinit romdata 0x000016 program 0x000004
MAIN_PROG code 0x000018 program 0x00018a
...
Hier taucht auch dein MAIN_SETUP auf, mit der Adresse, wo es im
Speicher steht und der Größe. Das ist nix anderes wie ein x-beliebiger
Name, was du dir frei wählen kannst.
Gast
#1454423
hier noch mal ein älters User' Guide, sieht auf den ersten Blick verständlicher aus.
@ ... hast sicherlich recht mit zuviel auf einmal, habe aber leider keine Zeit zum entspannend angehen lassen. Danke dir für die Mühe durch deine Antworten werde ich immer auf den richtigen Weg gelenkt, weiß mir leider nicht anderes zu Helfen als gleichzeitig soviel wie möglich an Wissen aus so viel wie möglich Quellen anzueignen. Bin echt auf euere Hilfe hier angewiesen, wenn ich euch nerve, tut mir leid. Werde mich weiter durchkämpfen und sicherlich weitere Fragen haben. Der Linker-Skript hat die Funktion den Programmspeicher zu verwalten, soweit ich es verstanden habe. Die Assembler-Syntax verstehe ich einigermaßen auch(muss jedes mal nachgucken was ein Befehl eigentlich macht), glaube ich zumindest. Was Sections sind weiß ich jetzt nicht oder vielleicht kenne ich nur das Wort nicht, aber schaue ich nach. Gucke mir auch die .map an. MfG Iwan
Gast
#1454495
wenn du dir das zweite Pdf anschaust, da ist es sehr gut beschrieben. Eine Section ist nix anderes wie ein Segment. Ein Linker-Skript beschreibt, wo welches Segment im Speicher liegt bzw. wo es beginnt/endet. Es ist nämlich so, dass der Programmcode, initialisierte bzw. nicht initialisierte Variablen nicht so einfach zusammen geschießen werden, sondern sie werden jeder in seinem eigenen Segment getrennt voneinander plaziert. Der Assembler übersetzt ein File in ein Objektfile und der Linker "sortiert" das Ganze (siehe dali.map) zu einem ausführbaren Code(Image).
aha es wird langsam klarer danke nochmal.
Gast
#1455357
Hi, ich habe hier noch mal in meiner Pdf-Sammlung geschaut und habe was für MPLINK gefunden. Ist ein bißchen übersichtlicher, als wenn alles zusammen in einem Dokument steht.
Gast
#1468829
ich nutze den thread hier mal weiter :> und zwar versuche ich mir grade assembler beizubringen "kann" bisher nur C erste frage/n :>
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
1. was hat es mit diesen R16 R17 usw. auf sich? mir ist klar das diese register zum speichern von variablen genutzt werden. ich meine irgendwo gesehen zuhaben das sie hardwareseitig existieren.... aber welcher art sind diese register? integer char....??? 2. kann man die nennen wie man will? oder woher weiß man welche man nutzen kann? 3. bzgl des pointers. gibt es nur den pointer Z? (ZL und ZH) oder kann man den nennen wie man will? außerdem betrachtet dieser pointer doch eine "fläche" nämlich den datensatz daten...ich kannte pointer bisher immer so das man damit einzelne inhalte in einem datensatz betrachtet :? 4. woher weiß lpm das ich die sachen nach R0 speichern will? ist das so standard? das wäre ja noch kein großes ding aber, was wenn ich mehrere pointer nutze?? woher weiß lpm dann welchen er nutzen soll?? oder wird einfach immer der zuletzt definierte genutzt? 5. globales fragezeichen ^^" gruß und danke für eure hilfe :}
Gast
#1468843
> 1. was hat es mit diesen R16 R17 usw. auf sich? mir ist klar das diese > register zum speichern von variablen genutzt werden. > ich meine irgendwo gesehen zuhaben das sie hardwareseitig existieren.... > aber welcher art sind diese register? integer char....??? Hängt von der Hardware ab -> Datenblatt. Die Interpretation liegt am Kontext -> Datenblatt. > 2. kann man die nennen wie man will? oder woher weiß man welche man > nutzen kann? Die benennt man i.d.R. so, wie sie der Assembler erwartet. Wie der das tut, das steht in dessen Datenblatt :-) > 3. bzgl des pointers. gibt es nur den pointer Z? (ZL und ZH) oder kann > man den nennen wie man will? Das hängt von der Hardware ab -> Datenblatt. Achja i.d.R. kann man Register 'umbenennen' im Sinne von 'Aliasen'. Details liefert die Doku zum Assembler :-) > außerdem betrachtet dieser pointer doch eine "fläche" nämlich den > datensatz daten...ich kannte pointer bisher immer so das man damit > einzelne inhalte in einem datensatz betrachtet :? Ein Pointer ist eine (Speicher)Adresse, nichts weiter. Die Interpretation obliegt dem Programmierer :-) > 4. woher weiß lpm das ich die sachen nach R0 speichern will? ist das so > standard? das wäre ja noch kein großes ding aber, was wenn ich mehrere > pointer nutze?? woher weiß lpm dann welchen er nutzen soll?? oder wird > einfach immer der zuletzt definierte genutzt? Das steht im Datenblatt in der Kategorie 'lpm' :-) Und obs Hardwareunterstützung für mehr Zeiger gibt ebenfalls :-) Im Großen und Ganzen kann man aber sagen: Je mehr RISC desto unwahrscheinlicher, je mehr CISC desto wahrscheinlicher. > 5. globales fragezeichen ^^" Nicht verzagen, Doku lesen. Vorzugsweise vollständig, auch wenn das u.U. ein paar hundert Seiten sind. Falls es weniger ist, dann hat man die falsche Doku erwischt. Zum Einstieg ist es sicher auch nicht verkehrt, die wichtigen Teile auszudrucken und altmodisch mit schmalen Farbspuren zu kennzeichnen ;-) HTH
gast schrieb: > ich nutze den thread hier mal weiter :> Aha, Du benutzt also auch nen PIC und hast Fragen zum Linker. Wenn nicht, dann laß das Hijacken und mach gefälligst nen eigenen Thread auf. Hijacken bringt bestenfalls Zufallstreffer, aber dafür den Thread gehörig durcheinander. Peter
Gast
#1469134
danke gast mir war nicht klar das das ganze SO hardware nah ist :)
@ Iwan Ne weiss nich obs dir weiterhilft oder ob du's schon kennst aber beste Seite um nen Einstieg in Pic und Assembler zu kriegen fand ich immer www.Sprut.de. viel Erfolg Felix
Gast
#1469887
ich bins nochmal :/
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
ich werde nicht schlau aus diesen stackpointern
1 | |
2 | |
3 | |
4 | |
kann es sein das man sowas in C garnicht hat? werden die nur dafür definiert, damit das programm zu einer funktion zurückfindet? denn wenn ich das ganze stackpointer zeugs auskommentiere verschluckt er sich beim rcall befehl... was mich außerdem auch noch stutzig macht ist: [code] inc r16 ;Datenwert erhöhen [code] wenn r16 als stackpointer genutzt wird...oder sind im register dafür extra bits freigestellt? dann kann man doch nicht einfach mit inc r16 das register neubeschreiben dadurch würde doch der pointer beschädigt :? da es aber funktioniert....was verstehe ich hier falsch? was ich auch schon öfter gesehen habe und mir immer noch schleierhaft ist... die warteschleife, warum steht da als label wait: und direkt darunter wait1:? gruß
gast schrieb: > ich bins nochmal :/ Aha FAng mal hier zu lesen an. http://www.mikrocontroller.net/articles/AVR-Tutorial Das erste Kapitel kannst du überspringen und gleich zu I/O Grundlagen weitergehen. Un dbesorg dir bei Atmel das Datenblatt zu deinem Prozessor sowie die Befehlscodereferenz > ich werde nicht schlau aus diesen stackpointern >
1 | |
2 | |
3 | |
4 | |
5 | |
> > kann es sein das man sowas in C garnicht hat? Doch der ist auch dort vorhanden. Nur brauchst du dich als C-Programmierer nicht darum kümmern. > denn wenn ich das ganze stackpointer zeugs auskommentiere verschluckt er > sich beim rcall befehl... Du lernst falsch. Einfach sinnlos ausprobieren führt nicht zum Ziel. > [code] > inc r16 ;Datenwert erhöhen > [code] > > wenn r16 als stackpointer genutzt wird... Wer sagt denn, dass r16 der Stackpointer ist? > die warteschleife, warum steht da als label wait: und direkt darunter > wait1:? 1) ist das nicht direkt darunter, sondern da sind ein paar Anweisungen dazwischen 2) Warum soll sich der Programmierer nicht mehrere Labels definieren, wenn er das möchte und es ihm sinnvoll erscheint, weil er einen Sprung genau auf diese Stelle machen möchte.
gast schrieb: > danke gast > mir war nicht klar das das ganze SO hardware nah ist :) Lass es mich mal so ausdrücken: Noch hardwarenäher geht nur indem du den Chip umätzt.
Gast
#1469917
>2) Warum soll sich der Programmierer nicht mehrere Labels definieren, >wenn er das möchte und es ihm sinnvoll erscheint, weil er einen Sprung >genau auf diese Stelle machen möchte. ok, wenn mehr nicht dahintersteckt ists ja in ordnung ^^ >Doch der ist auch dort vorhanden. Nur brauchst du dich als >C-Programmierer nicht darum kümmern. scho klar, so war das gemeint...das man nichts unwichtiges tippt ist ja logisch ^^ war blöd vormuliert an dem avr tutorial bin ich natürlich dran...nur manchmal sind da sprünge drin bei denen klemmt es dann etwas... mir ist z.b. nicht wirklich klar warum man immer high und low hat (bei pointern) ich habe das zwar so verstanden das sie aus zwei bits bestehen aber warum das so ist.....ka.. >Wer sagt denn, dass r16 der Stackpointer ist? vermutlich niemand... ich habe das nur so verstanden mit ldi läd man doch hier etwas in r16... und normalerweise das was hinter dem komma steht.. :?
1 | |
2 | |
gast schrieb: > an dem avr tutorial bin ich natürlich dran...nur manchmal sind da > sprünge drin bei denen klemmt es dann etwas... OK. Das kommt vor. Wir sind ja auch daran interessiert, das Tutorial zu verbessern. > mir ist z.b. nicht wirklich klar warum man immer high und low hat (bei > pointern) Weil eine Speicheradresse aus 16 Bit besteht, die Register aber nur 8 Bit breit sind. Also muss man Manipulationen, die 16 Bit betreffen, in 2 Schüben machen. Einmal mit den höherwertigen 8 Bit, einmal mit den 8 niederwertigen Bits. > ich habe das zwar so verstanden das sie aus zwei bits bestehen aber > warum das so ist.....ka.. Nicht 2 Bits. > mit ldi läd man doch hier etwas in r16... und normalerweise das was > hinter dem komma steht.. :? Ja schon. Aber was passiert denn danach ... Danach werden die Werte von r16/r17 in den tatsächlichen Stackpointer übertragen.
1 | |
2 | |
und damit sind die Register r16 und r17 wieder für andere Aufgaben frei. sph/spl ist der Stackpointer, nicht r16/r17. r16/r17 sind nur die Transportregister um die gewünschten Werte in den Stackpointer zu transportieren (weil es dafür keinen direkten Befehl gibt ... siehe Datenblatt)
gast schrieb: > an dem avr tutorial bin ich natürlich dran...nur manchmal sind da > sprünge drin bei denen klemmt es dann etwas... > mir ist z.b. nicht wirklich klar warum man immer high und low hat (bei > pointern) Weil ein Register 1 Byte enthält, Du aber zum Adressieren eines Adrssraumes von >256 Bytes (bzw. Words) 2 Bytes benötigst. Dazu werden 2 benachbarte Register zu einem Indexregister (=Pointer) zusammengesetzt. Eines davon beinhaltet den High-Teil und das andere den Low-Teil der Adresse. > ich habe das zwar so verstanden das sie aus zwei bits bestehen aber > warum das so ist.....ka.. 2 Bytes, nicht Bits >>Wer sagt denn, dass r16 der Stackpointer ist? > vermutlich niemand... > ich habe das nur so verstanden > mit ldi läd man doch hier etwas in r16... und normalerweise das was > hinter dem komma steht.. :? r16 und r17 werden in Deinem Beispiel nur als Zwischenstation für die Adressinformation benutzt. Der Assembler kann in die Speicherstellen des Stackpointers keine Werte direkt eintragen, dazu muß man den Umweg über die Register gehen.
1 | |
2 | |
Ja, aber das Entscheidende fehlt hier (ist aber in Deinem Beispiel oben enthalten):
1 | |
2 | |
Hier werden die Inhalte der Register in den Stackpointer geladen. Anschließend sind die beiden Register wieder für andere Aufgaben frei, behalten aber ihren Inhalt noch. Reinhard
Gast
#1469980
>Nicht 2 Bits. ist schon spät ^^" bytes natürlich sorry >Danach werden die Werte von r16/r17 in den tatsächlichen Stackpointer >übertragen. > out spl,r16 ;Stackpointer auf > out sph,r17 ;RAM-Ende setzen >und damit sind die Register r16 und r17 wieder für andere Aufgaben frei. >sph/spl ist der Stackpointer, nicht r16/r17. r16/r17 sind nur die >Transportregister um die gewünschten Werte in den Stackpointer zu >transportieren (weil es dafür keinen direkten Befehl gibt ... siehe >Datenblatt) danke dann sind mir die beiden spalten jetzt auch klar :) da muss ich mich echt erst dran gewöhnen :/ in c ballert man immer alles schön sofort dahin wo man es haben will (jedenfalls wirkt es so) >Wir sind ja auch daran interessiert, das Tutorial zu verbessern. bin immer wieder begeistert von der jetzt schon vorhandenen qualität des wikis und vor allem des forums! und super ist auch das ihr keine optischen emoticons aktiviert habt :) d/^_^\b
gast schrieb: > danke dann sind mir die beiden spalten jetzt auch klar :) > da muss ich mich echt erst dran gewöhnen :/ in c ballert man immer alles > schön sofort dahin wo man es haben will (jedenfalls wirkt es so) Du gibst auch einen Brief auf und irgendwie 'magisch' gelangt er an sein Ziel. Die Mechanismen die gahinter stecken, siehst du auch nicht und du musst dich auch nicht darum kümmen. ALs Assemblerprogrammierer bist du aber Briefschreiber, Verteilerzentrale, Postflugzeugführer und Zusteller in Personalunion.
@Karl heinz Buchegger (kbuchegg) (Moderator) Schöner Vergleich :-) @gast Was Karl Heinz sagen will (sorry Karl Heinz, daß ich Dich interpretiere), ist, dass Du beim Programmieren mit Assembler für jedes Detail selbst zuständig bist, bei Hochsprachen wird Dir vieles vom Compiler abgenommen. Gutes Beispiel ist der Stack. Der dient zum Speichern von Rücksprungadressen und zum Retten von Registerinhalten. Bei den Hochsprachen kümmert sich der Compiler komplett um dessen Organisation und Nutzung. Beim Assembler bist Du dafür zuständig. Du mußt den Stack erst mal initialisieren, d.h. dem Stackpointer sagen, ab welcher Adresse er seine Daten ablegen darf. Dazu mußt Du Dich im Datenblatt informieren, bei welchen Adressen Du den RAM findest (dort wird der Stack platziert). Du mußt Dir über die Arbeitsweise des Stack klar sein, er legt das zu speicherde Byte auf der aktuellen Adresse ab und zählt dann eine Adresse runter. Beim Lesen ist es umgekehrt, er erhöht seine Adresse und liest das dort liegende Byte. D.h. der Stackpointer braucht unterhalb seiner Initialisierungsadresse freien RAM. Deshalb wird er normalerweise auf die höchste RAM-Adresse initialisiert. Ausnahmen nicht ausgeschlossen. Dann bei der Verwendung selbst darauf achten, daß alle eingelagerten Daten vollständig und in der richtigen Reihenfolge wieder entnommen werden. Sonst droht Stacküberlauf und Dein Programm stürzt ab. D.h. Call und Ret bzw. Push und Pop richtig schachteln. Es gibt noch viele andere Sachen, die man beim Programmieren mit Assembler beachten muß. Die wichtigsten Informationsquellen sind dabei das Datenblatt des Prozessors, die Befehlsbeschreibung und die Anleitung für den benutzten Assembler. Für den allseits beliebten ATmega8 mal die Links zu den Infos: Datenblatt http://atmel.com/dyn/resources/prod_documents/doc8159.pdf Instruction Set http://atmel.com/dyn/resources/prod_documents/doc0856.pdf wobei die implementierten Befehle für den verwendeten Prozessor am Ende dessen Datenblatts aufgeführt sind. Zum Programmieren in Assembler bietet sich das "AVR Studio 4" an: http://atmel.com/forms/software_download.asp?fn=dl_AvrStudio417Setup.exe ist gratis, mußt Dich aber registrieren. Die dort enthaltene Hilfe ist recht umfangreich, die Befehle sind dort auch alle noch mal erklärt. Ich wünsche Dir noch viel Erfolg beim Einarbeiten. Und immer dran denken: Beim Assembler kennst Du noch jedes Bit persönlich :-) Reinhard
Gast
#1471219
danke für den ausführlichen post :) das meiste ist mir davon aber schon klar ich habe vor einiger zeit schon einmal angefangen atmel prozessoren zu programmieren aber in C, da ich da noch ganz gut drin bin durchs studium... je mehr ich mich aber damit beschäftigt habe, je mehr wurde mir persönlich klar C und µCs ist für mich nicht so das wahre...atmel scheint das ja auch so zu sehen :P daher die idee das ganze noch mal von vorn zulernen...glücklicherweise erfindet man bei programmiersprachen ja nicht das rad neu, so dass das ganze zügig gehen sollte habe heute zum reinfinden erstmal mit hilfe der im wiki stehenden lcdlib eine eigene lcd libary geschrieben... und in C kann man echt nicht auf den stack zugreifen? finde das mittlerweile recht nützlich. hat es eigentlich geschwindigkeitsvorteile, wenn man den stack als variable nutzt? atm nutze ich es nur zum variablen sichern....da der pointer aber immer auf einen freien stack slot zeigt kam mir der gedanke das es evtl. schneller ist dort als in einem register zuspeichern :? davon abgesehen finde ich den assembler syntax deutlich schöner und kein nerviges ";" am ende jeder zeile :D
gast schrieb: > und in C kann man echt nicht auf den stack zugreifen? finde das > mittlerweile recht nützlich. > hat es eigentlich geschwindigkeitsvorteile, wenn man den stack als > variable nutzt? Genau dafür benutzt dein C-Compiler zb den Stack: Um dort lokale Variablen anzulegen :-) > auf einen freien stack slot zeigt kam mir der gedanke das es evtl. > schneller ist dort als in einem register zuspeichern :? ??? Entweder du drückst dich jetzt ungeschickt aus, oder du hast nicht verstanden, was es mit den Registern auf sich hat. > davon abgesehen finde ich den assembler syntax deutlich schöner und kein > nerviges ";" am ende jeder zeile :D Dafür musst du dich um jeden Scheiss selber kümmern int main() { int y; DDRA = 0xFF; while( 1 ) { y = PIND; PORTA = y * PINB / 3; } } Schreib diesen 5-Zeiler mal in Assembler, so dass er exakt das gleiche Verhalten hat. Danach wirst du die "nervigen ';'" nur noch als Peanuts ansehen :-) PS: > habe heute zum reinfinden erstmal mit hilfe der im wiki stehenden > lcdlib eine eigene lcd libary geschrieben... Warum blos nehme ich dir das nicht ab :-)
Gast
#1471253
>??? >Entweder du drückst dich jetzt ungeschickt aus, oder du hast nicht >verstanden, was es mit den Registern auf sich hat. ich stelle mir das als lange liste aus registern vor...der stack füllt diese von rechts und ich idealerweise von links >Schreib diesen 5-Zeiler mal in Assembler, so dass er exakt das gleiche >Verhalten hat. Danach wirst du die "nervigen ';'" nur noch als Peanuts >ansehen :-) glaub ich dir gerne >Warum blos nehme ich dir das nicht ab :-) ja, warum bloß? aber wo wir gerade dabei sind, bei einer sache harkt es.. und zwar beim auslesen von strings per zeiger mir ist nicht 100% klar warum das so funktioniert wie es funktioniert zitat von irgendwo >Für das Lesen aus dem Programmspeicher gibt es nur den Zeiger Z und den >Befehl LPM. Er lädt das Byte an der Adresse Z in das Register R0. hier wird aber direkt nach r16 gespeichert oder nicht :? 2. fängt z IMMER bei 0 an zuzählen? könnte doch auch sein das da zufällt eine zahl drin steht und dann fängt er mitten im string an zuzählen :?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
gruß
Gast
#1471260
Hi >Er lädt das Byte an der Adresse Z in das Register R0. >hier wird aber direkt nach r16 gespeichert oder nicht :? Wenn du wirklich in Assembler programmieren willst (mach ich selbst ausschließlich), solltest du dir wenigstens mal das Instruction Set zu Gemüte führe. LPM nach r0 war bei den ersten AVRs die alleinige Möglichkeit. Beiden neueren geht das für jedes Register. MfG Spess
gast schrieb: >>??? >>Entweder du drückst dich jetzt ungeschickt aus, oder du hast nicht >>verstanden, was es mit den Registern auf sich hat. > > ich stelle mir das als lange liste aus registern vor...der stack füllt > diese von rechts und ich idealerweise von links [ ] Du hast es verstanden [x] Du hast nicht verstanden, was ein Register ist. >>Warum blos nehme ich dir das nicht ab :-) > ja, warum bloß? Weil du hier bei den simpelsten Dingen die abenteuerlichsten Fehler machst. Du hast vielleicht die LCD-Funktionen abgeschrieben. Aber du hast sie nicht selbst geschrieben. Malen nach Zahlen hat mit dem was ein echter Maler tut nicht sehr viel gemeinsam. >>Für das Lesen aus dem Programmspeicher gibt es nur den Zeiger Z und den >Befehl > LPM. Er lädt das Byte an der Adresse Z in das Register R0. > hier wird aber direkt nach r16 gespeichert oder nicht :? Wo? > 2. fängt z IMMER bei 0 an zuzählen? z enthält den Wert, den du reinladest. > könnte doch auch sein das da zufällt > eine zahl drin steht und dann fängt er mitten im string an zuzählen :? > > [code] > lcd_flashstr: > push r16 > push ZH > push ZL > > > flashstr1: > lpm r16, z+ <<<<<<<<< HIIIIIIIER Datenblatt/Instruction Set lesen. Es gibt mehrere Varianten dieses Ladebefehls.
Gast
#1471273
>solltest du dir wenigstens mal das Instruction Set zu Gemüte führe omfg ist das viel o.O gibt es denn nichts einfaches auf dieser welt :lol: >LPM nach r0 war bei den ersten AVRs die alleinige >Möglichkeit. ich hatte das mehrfach gelesen deshalb als richtig abgespeichert :/ >Wo? da! >lpm r16, z+ <<<<<<<<< HIIIIIIIER
Gast
#1471303
Hi
>ich hatte das mehrfach gelesen deshalb als richtig abgespeichert :/
Ist ja auch nicht falsch.
lpm -> r0
lpm r16,Z (+) -> r16
MfG Spess
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.