Hallo,
ich debugge gerade ASM-Code für einen Atmega128 der von einem Vorgänger
(Studienarbeit an der Uni) verbrochen wurde. Dokumentation des Codes
geht quasi gegen 0 und ich habe die ehrenvolle Aufgabe, nun die
Fehlerursache zu finden.
Ich bin dabei nun mehrfach auf folgendes Konstrukt gestoßen mit dem ich
irgendwie nicht viel anfangen kann:
1
sts PORTG, r24
2
sts DDRG, r24
3
lds r24, PORTG
Ich meine hierbei das letzte "lds". Dort passiert nach meinem
Verständnis ja nichts anderes, als dass der Wert, der von r24 nach PORTG
geladen wurde wieder zurück nach r24 geladen wird, die Anweisung könnte
man also auslassen da sie ja nichts anderes macht als "r24 = r24", oder
sehe ich das falsch? Denn an PORTG anliegende Signale müssten ja mittels
Ina schrieb:> die Anweisung könnte> man also auslassen da sie ja nichts anderes macht als "r24 = r24", oder> sehe ich das falsch?
Wenn er nicht gerade die verplemperten Taktzyklen für das Timing
braucht ;-), ja. Ist ein teurer NOP.
> Denn an PORTG anliegende Signale müssten ja mittels> lds r24,PING>> eingelesen werden, oder?
So ist es.
Darf ich fragen, was der Code überhaupt macht?
Ungewöhnlich, dass man mitten im Code das DDR Register umsetzt.
Normalerweise stellt man die am Programmanfang einmal korrekt ein, und
dann bleibt das auch so.
Kann natürlich auch sein, dass der Portpin bewusst zwischen Ein/Ausgang
hin und hergeschaltet wird, um an einem Ausgangspin die Zustände
High-Low-Tristate zu erreichen. Das kommt aber nicht so oft vor und der
abschliessende LDS weckt dann nicht wirklich das Vertrauen in mir.
Hallo,
diese Stelle taucht nicht mitten im Programm auf sondern beim
Progbrammstart, das hatte ich vergessen zu erwähnen. Die "normalen"
I/O-Ports werden wie üblich konfiguriert aber bei den Ports die im
extended I/O liegen fängt er dann plötzlich mit solchen Geschichten an.
An Port G hängt zwar auch ein DSP, aber dadurch dass ja eben nicht PING
eingelesen wird kann es ja eben nicht sein, dass dort irgendwelche
Signale ausgewertet werden. ich weiß nun nicht wie fit mein Vorgänger in
ASM war, vielleicht ist es tatsächlich nur ein teures NOP weil er dachte
er müsste zwingend die zwei Zyklen überbrücken bis das STS fertig ist
o.ä., ich wollte mich nur nochmal absichern dass mit solch einer
Befehlskombination nicht möglicherweise irgendetwas ganz "Abgedrehtes"
gemacht werden kann ;)
Gruß,
Ina
Hi
> oder?
Nicht unbedingt. Das Portregister hat auch noch die Aufgabe bei
Eingängen den Pull-Up-Widestand einzuschalten. Also kann es durchaus
sinnvoll sein dieses auszulesen. Für den Zustand der Eingänge wäre
natürlich PING richtig.
MfG Spess
Das Umschalten eines Ports oder Teile davon
kann schon mal vorkommen, wenn der Port Bidirektionales
IO macht.
Daß das Register des Ports zurückgelesen wird kann
den Grund haben: z.B. ein am Port hängender Transistor
zieht den Pin beim H-Zustand "zuweit" runter und der
PIN liest dann eine 0 statt einer 1 zurück.
Ohne nähere Info zur HW halte ich mich mal mit
evtl. bösen Kommentaren zurück.
Hier würde ich aber mal nach dem Fehler suchen.
spess53 schrieb:> Hi>>> oder?>> Nicht unbedingt. Das Portregister hat auch noch die Aufgabe bei> Eingängen den Pull-Up-Widestand einzuschalten. Also kann es durchaus> sinnvoll sein dieses auszulesen.
Schon.
Aber in diesem Zusammenhang und unter Berücksichtigung des Faktums, dass
immer das gleiche Register r24 involviert ist, macht es nicht wirklich
großartig Sinn
ldi r24, 0xAA
sts PORTG, r24
sts DDRG, r24
lds r24, PORTG
was soll in r24 jetzt stehen, ausser 0xAA?
Er schaltet die Pins auf 1, dann auf Ausgang. Bis daher ist das noch
sinnvoll. Aber wozu das zurücklesen?
Man muss nicht immer in merkwürdigem Code nach Sinn suchen, jedoch gäbe
es eine Bedingung, d.h. wenn ein Interrupt PORTG verändern kann, bei der
dieser Code dann nicht mehr einem einfachen MOV R24, R24 entspricht. Da
käme es auf das weitere Code-Umfeld an.
Anton schrieb:> Daß das Register des Ports zurückgelesen wird kann> den Grund haben: z.B. ein am Port hängender Transistor> zieht den Pin beim H-Zustand "zuweit" runter und der> PIN liest dann eine 0 statt einer 1 zurück.
Nein, den Grund hat's sicher nicht. Wenn der Portpin mit Gewalt gezogen
wird, kann man das nicht durch Lesen des Port-Registers raus bekommen,
da muss man Pin lesen.
Anton schrieb:> zieht den Pin beim H-Zustand "zuweit" runter und der> PIN liest dann eine 0 statt einer 1 zurück.
Dann müsste er aber das Pin Register auslesen. Aus dem Port Register
kriegt er genau den Wert wieder raus, den er vorher reingeschrieben hat.
MWS schrieb:> Man muss nicht immer in merkwürdigem Code nach Sinn suchen,
Ist für mich eine Frage der Vertrauensbildung.
Kann natürlich auch sein, dass das ein Überbleibsel von früher oder ein
Copy&Paste Fehler ist.
Macht er denn in weiterer Folge irgendwas mit dem Wert in r24?
Das ist für mich bei Analysen meistens ein ganz guter Leitfaden. Die
Überlegung: OK, da wird also ein Wert geholt - was macht er damit?
Hm mal ne Spekulation bin in AVR ASM nicht so fit, aber z.b. bei PICs
wird das auch öfters gemacht z.b. um nen Statusbit zu setzen b.z.w. nen
Resultat in nem Statusbit zu bekommen, allerdinks müsste dann im
folgecode was dementsprechend auftauchen.
Karl Heinz Buchegger schrieb:> MWS schrieb:>> Man muss nicht immer in merkwürdigem Code nach Sinn suchen,>> Ist für mich eine Frage der Vertrauensbildung.
Meine Aussage war: manchmal ist Blödsinn einfach nichts weiter als
Blödsinn.
Karl Heinz Buchegger schrieb:> OK, da wird also ein Wert geholt - was macht er damit?
Genau darauf sollte man achten und das schrieb ich:
> Da käme es auf das weitere Code-Umfeld an.
Ina schrieb:> ich debugge gerade ASM-Code für einen Atmega128
...
> ich habe die ehrenvolle Aufgabe, nun die> Fehlerursache zu finden.
Der Fehler wird sein, daß man 128kB einfach nicht mehr in Assembler
programmieren kann.
Schmeiß alles weg und schreibs in C.
Assembler nehme ich nur für sehr kleine Programme (unter 2kB).
Peter
Ich habe damit wohl meinem Vorgänger Unrecht getan, ich muss jetzt
erstmal klären woher dann dieser ASM-Code kommt, bzw. warum mir kein
C-Code zur Verfügung gestellt wird. Auf jeden Fall schonmal vielen Dank
für eure Hilfe, wieder was gelernt :)
Gruß,
Ina
Peter Dannegger schrieb:> Der Fehler wird sein, daß man 128kB einfach nicht mehr in Assembler> programmieren kann.
Ähm, naja, also, um zumindest für mich persönlich diese Sache einmal zu
klären habe ich vor ca. 12 Monaten ein Projekt begonnen, das inzwischen
auch langsam fertig wird.
Ich habe hier einen Heimcomputer komplett aus parallel arbeitenden AVRs,
mehr als 15 Grafikmodi, Raster-IRQ, SD-Laufwerk,
6502/6510/Z80/6809-Interpreter, alles durchgetaktet, in Echtzeit mit
2MHz bei 24MHz-Systemtakt. Alles komplett durchoptimierter Assemblercode
bzgl. Laufzeit und über 128kB dürfte ich locker drüber liegen. Die
einzelnen AVRs sind komplett über den gesamten Code Taktgenau
synchronisiert um die hohe Geschwindigkeit zu erreichen, absolut
unmöglich das per Compiler zu machen.
Und das 'Ding' läuft :-) Weiß noch nicht, was ich damit überhaupt
anfange und ob ich es evtl. veröffentliche, aber prinzipiell können kann
'man' auch viele zehntausend Zeilen sinnvollen und hochoptimierten
Assemblercode schreiben, der Beweis steht hier neben mir.
Mag sein bzw. würde mich inzwischen nicht mehr wundern, dass das etwas
sehr ungewöhnlich ist, wie bspw. Pi auf über 22.000 Stellen aufsagen,
kann ich selbst so wenig, wie die meisten anderen. Aber da kann 'man' ja
auch nicht mehr allgemein sagen, 'man' könne es nicht sondern muss sagen
'ich' kann es nicht. Dafür darf man sich dann freuen eine Gemeinsamkeit
mit 99,irgendwas Prozent aller Menschen zu haben :-)
Ich will auf keinen Fall eine Diskussion zu dem Thema Assembler
verursachen, ich wollte nur mal die Gelegenheit wahrnehmen, diese
althergebrachte Behauptung mit Fakten zu widerlegen. Jemand sagte zwar
mal, dass ein Vorurteil in der heutigen Zeit schwerer zu zertrümmern
sei, als ein Atom, aber vielleicht kann ich dieses Dogma ja mal etwas
ankratzen. ;-)
Ontopic:
Es war keine Rede von der Programmgröße auf dem mega128. Und 64.000
Zeilen Code schreiben, dürfte für eine Studienarbeit schon vom reinen
Tippen her zuviel Arbeit sein. Und irgendwie wage ich zu bezweifeln,
dass die 'freiwillig' Assembler verwenden, wenn's nicht die
Aufgabenstellung vorschreibt. Da wird vermutlich ein typischer
Anfängerfehler wie PORTG und PING vertauscht oder so drin sein.
Grüße
Mark
Mark L. schrieb:> Ich habe hier einen Heimcomputer komplett aus parallel arbeitenden AVRs,> mehr als 15 Grafikmodi, Raster-IRQ, SD-Laufwerk,> 6502/6510/Z80/6809-Interpreter, alles durchgetaktet, in Echtzeit mit> 2MHz bei 24MHz-Systemtakt.
Faszinierend! Respekt!
Mark L. schrieb:> Ähm, naja, also, um zumindest für mich persönlich diese Sache einmal zu> klären habe ich vor ca. 12 Monaten ein Projekt begonnen, das inzwischen> auch langsam fertig wird.> Ich habe hier einen Heimcomputer komplett aus parallel arbeitenden AVRs,> mehr als 15 Grafikmodi, Raster-IRQ, SD-Laufwerk,> 6502/6510/Z80/6809-Interpreter, alles durchgetaktet, in Echtzeit mit> 2MHz bei 24MHz-Systemtakt. Alles komplett durchoptimierter Assemblercode> bzgl. Laufzeit und über 128kB dürfte ich locker drüber liegen. Die> einzelnen AVRs sind komplett über den gesamten Code Taktgenau> synchronisiert um die hohe Geschwindigkeit zu erreichen, absolut> unmöglich das per Compiler zu machen.
WILL! DAS! DING! SEHEN!!! Unbedingt ;)
Ich mache hier übrigens gerade etwas ähnliches - eine kleine
Spielekonsole mit 2 ATMega1284P. Einer als Grafikprozessor und einer als
"Großhirn". Das Teil schafft eine Grafikauflösung von 160x100 bei 64
Farben :D. Aber bei mir sind nur die Takte der Grafikausgabe handgezählt
und auf eine bestimmte Laufzeit getrimmt, der Rest läuft mit einfachen
Interrupts ;). Im Großhirn wird dann ein CPU-Emulator laufen - ich peile
da so 500k bis 1M Instruktionen pro Sekunde an...
Gruß
Jonathan
P.S.: Sorry für's OT
Peter Dannegger schrieb:> Der Fehler wird sein, daß man 128kB einfach nicht mehr in Assembler> programmieren kann.
Hmmm ... mit 64kB geht es noch ...
> Schmeiß alles weg und schreibs in C.
Halte ich für Unsinn!
Gruß
Jobst