Hallo Leute,
habe da ein sehr merkwürdiges Problem.
Ich programmiere in Assembler mit AVR-Studio 4.15 seit Wochen einen
ATmega162 ohne Probleme. Heute habe ich festgestellt, daß das immer
größer werdende Programm nicht mehr fehlerfrei funktioniert. Nach
stundenlanger Eigenfehlersuche habe ich festgestellt, daß das passiert
sobald der Programmcode 5052 Programmwörter also 10040 Bytes erreicht.
8192 PW oder 16384 Bytes sollten mir aber zur Verfügung stehen.
Das erste was ich dachte war: DAS GLAUBT MIR KEINER !
Jetzt ist natürlich ein Programmierfehler nahe liegend aber zwei Gründe
sprechen dagegen:
1. Ich kann keinen Fehler finden ( OK, zählt nicht ;-)
nochmal 1. Wenn ich die Codeerweiterung bis 5050 PW entferne
funktioniert es.
Wenn ich dann z.B. unter die Zeile
1
ldsr16,s_MeinRAM
einfach nochmal
1
ldsr16,s_MeinRAM
eintippe,(banal oder) dann kann ich es ohne Fehlermeldung assemblieren,
komme auf 5052 PW und das Programm funktioniert nicht mehr.
Unfassbar ! Ich verwende nicht den M161C Modus und als Sprungadressen
keine nummerischen Absolutwerte, nur Sprungmarken und PC+x also:
1
rjmpPC+2
1
rjmpMeinZiel
Ne Ferndiagnose ist sicher nicht einfach, aber hat vielleicht einer
einen Tipp oder Denkanstoß.
Bin wahrscheinlich schon zu Programmblind.
MfG
Ak Tronik
Das stimmt, aber wenn ein rjmp nicht ausreicht bekommt man die
Fehlermeldung:
error : Relative branch out of reach
Das Assemblieren funktioniert ja.
MfG
Ak Tronik
>Das stimmt, aber wenn ein rjmp nicht ausreicht bekommt man die>Fehlermeldung:>> error : Relative branch out of reach>>Das Assemblieren funktioniert ja.
Vieleicht hat sich der Assembler einfach nur verrechnet?
Was beinhaltet denn die Codeerweiterung ?
Wird dort vielleicht ein Register verwendet, dass das nicht gesichert
wird oder was in der Art.
Ein Pointerüberlauf ?
Was passiert den, wenn das funktionierende Programm statt durch die
Codererweiterung" nur um NOPs ergänzt wird, bis 5052 Programmwörter
überschritten werden ?
mfg
SH
Erst mal DAnke für Eure Antworten.
@ Holger
>Vieleicht hat sich der Assembler einfach nur verrechnet?
Hmm, geht so was?
Ich werde mal alle rjmp durch jmp ersetzen.
Kann es leider erst Morgen auf den µC übertragen :-(
@brummbaer
>Was beinhaltet denn die Codeerweiterung ?
Die Erweiterung nimmt z.Zt. keinen logischen Einfluss auf das Programm.
Die geänderten RAM-Inhalte werden woanders nicht kontrolliert:
1
lds r16,s_Tx0ToSend
2
cbr r16,1<<TeachInToSend
3
sts s_Tx0ToSend,r16
4
5
lds r16,s_Tx0JustSending
6
cbr r16,1<<TIJustSending
7
sts s_Tx0JustSending,r16
r16 kann an dieser Stelle auch benutzt werden.
>Ein Pointerüberlauf ?
Der Programmzeiger und die XYZ-Register werden durch die Erweiterung
nicht gesetzt.
>Was passiert den, wenn das funktionierende Programm statt durch die>Codererweiterung" nur um NOPs ergänzt wird, bis 5052 Programmwörter>überschritten werden ?
Kann ich leider erst Mogen testen und werde dann Bericht erstatten.
Danke für Eure guten Denkanstöße :-)
Aber es ist schon merkwürdig oder?
Mfg
Ak Tronik
Hallo Ak Tronik,
mit 5052 solltest du noch weit vom Bootsektor entfernt sein
wenn das Programm von 0 ab linear im Speicher liegt.
Aber schau doch trotzdem, ob nicht der Bootbereich schreibgeschützt
ist und daher dein Programm ab dieser Grenze nicht angenommen wird.
avr
Sooo, hab jetzt einiges getestet.
Fuse Bits:
BOOTSZ steht auf $1F80. Davon bin ich weit entfernt.
BODLEVEL 4,3V (spielt keine Rolle)
SPIEN ist eingeschaltet
Sonst nichts
Lock Bits:
LB aus
BLB0 aus
BLB1 aus
Alle rjmp in jmp ändern habe ich verworfen weil ich dann auch alle rjmp
PC+X mit ändern muss. Da ist der nächste Fehler schon vorprogrammiert.
Dann habe ich die funktionierende Version am Programmanfang mit NOP
aufgefüllt:
Ohne NOP´s 5038 Wörter, mit zusätzlichen 9 NOP´s also 5047 Wörter
„spinnt“ das Programm. Nehme ich ein NOP raus, funktioniert es.
1
main: cli
2
ldi r16,low(ramend) ;Stack initialisieren
3
out SPL,r16
4
ldi r16,high(ramend)
5
out SPH,r16
6
7
nop
8
nop
9
nop
10
nop
11
nop
12
nop
13
nop
14
nop
15
16
nop ; mit dem NOP geht es nicht mehr!
ich werd noch irre! Was ist denn das für ein Mist, den ich übersehe?
MfG
Ak Tronik
Hallo,
naja, ohne alles zu kenne kann man nur raten...
Mögliche Variante: es werden Daten aus dem Flash gelesen statt aus dem
Ram oder es werden Daten aus einer Flashtabelle mit falscher
Adressberechnung gelesen.
Solange das Flash dor leer ist wird 0xFF gelesen und Dein Programm ist
damit (zufällig?) zufrieden. Ist dort Programm wird was anderes gelesen
und es stürzt ab.
Tabellenadresse wird berechnet und der Übertrag falsch ausgewertet oder
ignoriert. Berechneter Sprung oder Bedingung, wo signed/unsigned Branch
falsch ist.
In der Art gibt es noch genug Fehlerquellen...
Gruß aus Berlin
Michael
@ Michael U.
Also, LPM benutze ich nicht. Allerdings werden nicht wenige RAM-Adressen
berechnet und ich habe festgestellt, daß der Assembler bei der Eingabe:
1
lds r16, $1B00
2
sts $1B00,r16
nicht meckert, obwohl es beim assemblieren feststellbar wäre.
Die berechneten Adressen sind natürlich LD r16,X und ST Y,r16
Instruktionen.
Aber wenn da was schief läuft, dann doch auch in der "kurzen"
Programmversion !?!
MfG
Ak Tronik
Ak Tronik schrieb:
> Hmm automatisches Wraparound , kenn ich gar nicht. Wo stellt man das> denn ein?
Indem man das passende Include einbindet: "m162def.inc".
Welchen Assembler benutzt Du denn?
Es muß der avrasm2.exe sein.
In Assembler 10kB vollzukriegen ist schon recht sportlich.
Ich wär da schon längst auf C umgestiegen, weil ich total den Überblick
verloren hätte.
Assembler mache ich maximal bis 1kB.
Peter
Hi Peter,
"m162def.inc" ist drin.
Ich benutze AVRStudio.exe. Unter "Assembler Options" ist Avr Assembler
Version 1 angehakt und jetzt erst sehe ich "Wrap relative jumps".
Habe ich vorhin übersehen.
Wenn ich "Wrap relative jumps" anhake und assembliere ändert das nichts
am Ergebnis :-(
Jetzt kann ich auch nicht einfach Version 2 auswählen und assemblieren
ohne daß der Assembler die .def anmeckert.
Muss mal eben raus finden, was er statt .def gern hätte.
>In Assembler 10kB vollzukriegen ist schon recht sportlich.
Es finden u. A. 60.000 Sensorabfragen/s statt + Auswertung und dass
während gerade parallel Strings mit 115200 bit/s gesendet und empfangen
werden und Usereingaben abgefragt und...und...und.
Da hätte ich in C meine Schwierigkeiten.
MfG
Ak Tronik
Ak Tronik schrieb:
> Es finden u. A. 60.000 Sensorabfragen/s statt + Auswertung und dass> während gerade parallel Strings mit 115200 bit/s gesendet und empfangen> werden und Usereingaben abgefragt und...und...und.> Da hätte ich in C meine Schwierigkeiten.
Mir würde es genau umgekehrt gehen :-)
In Assembler müsste ich mich da mit viel zu viel 'Nebenbei',
Registerverwaltung etc. rumplagen. Das überlass ich lieber dem Compiler
und konzentrier mich auf die Verfahren.
Nun ja, geht bestimmt auch in C aber der Code würde sicherlich langsamer
und größer werden. Gerade der Überblick über die Workregister und RAM
macht schnellen Code möglich.
Ein Compiler verwurstet teilweise das 5-fache.
Ich kann es in Assembler besser, andere in C.
MfG
Ak Tronik
Hi
>Jetzt kann ich auch nicht einfach Version 2 auswählen und assemblieren>ohne daß der Assembler die .def anmeckert.>Muss mal eben raus finden, was er statt .def gern hätte.
Wenn du Assembler2 benutzten willst reicht es, wenn du die "m162def.inc"
ohne Pfadangabe einbindest. Der assembler benutzt dann die Richtige.
Mfg Spess
Hi,
s/r03/s3/
bedeutet:
substitude "r03" with "s3"
(search and replace)
Gruß
Olaf
PS: Gib mal an der Kommandozeile in der Linux-Distributuin Deiner Wahl
ein:
"info sed" (es handelt sich nämlich um ein sed Kommando.
Hmm, so viel ich weiss ist die Stackgröße nur von der (freien) RAM-Größe
abhängig. Ich gehe maximal 5 Level tief eher 4. Vom RAM-Ende bin ich
weit entfernt.
Ich werde das Programm wohl oder übel im Simulator debuggen, was aber
extrem aufwendig ist da der Fehler ja nicht direkt beim Starten
auftritt,
sondern mehrere Millionen Instruktionen danach.
MfG
Ak Tronik
Ak Tronik schrieb:
> Ich kann es in Assembler besser, andere in C.
Und wohin das dann führt, kann man ja hier recht gut sehen. Du hast
einen riesigen Berg ASM-Code, einen merkwürdigen Fehler, und keine so
rechte Idee, wo in dem großen Haufen Code du mit der Fehlersuche
ansetzen sollst. ;-)
Außerdem muss es ja kein entweder-oder sein. Deine Beschreibung oben
klingt für mich z.B. nach einer kleinen in ASM handkodierten ISR für die
Sensorabfrage und einer menge zeitlich unkritischen Kram drumherum in C.
Aber um nicht nur zu stänkern, sondern auch was konstruktives
beizutragen: ;-)
Würde es groß auffallen, wenn das Programm zwischendurch von vorn
anfängt? Wenn nein wäre auch folgendes Szenario denkbar: das Programm
springt zu einer falschen Adresse (z.B. (i)ret bei korrupten Stack).
Solange das Ziel dieses Sprungs der unbenutzte Bereich ist, fällt es
nicht weiter auf, weil die FFs dort als NOP interpretiert werden, und
das Programm dann nach dem Wrap-Around am Ende einfach von vorne
startet. Bei wachsendem Code ist am Sprungziel aber irgendwann
"richtiger" Code und keine FFs mehr, und es knallt richtig.
@ Stefan Ernst
>Und wohin das dann führt, kann man ja hier recht gut sehen. Du hast>einen riesigen Berg ASM-Code, einen merkwürdigen Fehler, und keine so>rechte Idee, wo in dem großen Haufen Code du mit der Fehlersuche>ansetzen sollst. ;-)
Ok, 1:0 für Dich !
Aber es ist ja so, daß ich mit dem Programm auch klein begonnen habe.
Das war vor Monaten auf dem ATmega8515. Als der dann nach steigenden
Anforderungen zu klein wurde, bin ich vor einigen Wochen auf dem
ATMega162 umgestiegen. Nun ist der Code zwar effektiv aber auch groß
geworden, daß ich vielleicht auf den Atmega644P umsteigen muß, weil ich
ihn schneller laufen lassen kann.
Hätte ich das in der 1. Woche gewusst, wäre die Entscheidung sicherlich
auf C gefallen.
Aber ein in Monaten erstelltes ASM-Programm, schreibt man dann auch
nicht eben um in C.
>Außerdem muss es ja kein entweder-oder sein. Deine Beschreibung oben>klingt für mich z.B. nach einer kleinen in ASM handkodierten ISR für die>Sensorabfrage und einer menge zeitlich unkritischen Kram drumherum in C.
Nein, die ISR sind sehr klein gehalten (Flags setzen) und der große Teil
ist zeitkritisch.
>Würde es groß auffallen, wenn das Programm zwischendurch von vorn>anfängt?
Ja, absolut. Es wird ein Display mit Wartezeit initialisiert.
MfG
Ak Tronik
Wenn Du Deine NOPs ans Ende setzst, ergibt sich dann immer noch der
Fehler? Vermutlich doch nicht.
Falls dem so ist: Versuche doch mal, die Position des Fehlers
quadratisch einzugrenzen (NOPS in die Mitte, dann auf die ca. Hälfte
usw.).
Ak Tronik schrieb:
> Alle rjmp in jmp ändern habe ich verworfen weil ich dann auch alle rjmp> PC+X mit ändern muss. Da ist der nächste Fehler schon vorprogrammiert.
Warum?
Traust Du dem Assembler nicht?
Glaub mir, der kann besser rechnen als Du.
Mach es!
Der Assembler1 wurde lange nicht mehr gepflegt, es könnte also gut sein,
daß er Bugs enthält.
Dunkel erinnere ich mich, es gab den .DB Fehler, d.h. nach ner
.DB-Anweisung mit ungeraden Bytes hat er den PC falsch berechnet.
Das "Wrap relative jumps" ist nur bis 8kB erlaubt, muß also unbedingt
ausgeschaltet sein!
Das sollte der Assembler aber automatisch machen, wenn das richtige
Include genommen wird.
Ohne Dich kritisieren zu wollen, die 10kB Assembler lassen vermuten, daß
der Code wenig strukturiert ist, d.h. viele ähnlich Programmteile
hintereinander enthält (der gefürchtete Spaghetticode).
Dann gerät man schnell zu dem Trugschluß, daß die CPU am Anschlag läuft,
weil viele Funktionsteile unnötig oft durchlaufen werden, weil man den
Überblick verloren hat.
Man denkt, ein C-Programm würde noch langsamer und größer. Aber das
Gegenteil ist der Fall, durch die Strukturierung werden Programme in der
Regel schneller und kleiner.
Peter
Hi!
Ob dein Code spinnt oder dein µC musst du doch rausfinden können.
Wie wäre es mit einem
.org 0x2774
Das ist PW 5050. Ab da schreibst du einfach ein kleines Prog.
was zb. die UART bedient. Es könnte natürlich sein das der ASS das dann
sauber übersetzt. Die Kontrolle des *.lst File könnte den Assembler
entlarven, wenn er denn Mist macht. Oder besser 2 .lst File machen,
einmal bis 5051PW und dann mit 1-2 NOP.
Die kann man ja vergleichen lassen.
Einen anderen µC haste schon getestet?
Achja, welchen Mist macht denn das Prog. plötzlich? Lässt sich da was
eingrenzen?
Übrigens 5052 PW sind 10104 Byte
>weil die FFs dort als NOP interpretiert werden
Ist das wirklich so, weil NOP =$0000 und nicht $FFFF.
Das könnte eher SBRS sein.
> Aber das Gegenteil ist der Fall, durch die Strukturierung werden> Programme in der Regel schneller und kleiner.
Aber auch nur wenn der Programierer strukturiert proggt.
In ASM kann man das genauso, wobei ca.5000 Zeilen schon recht heftig
ist.
Auch in C sind das nicht wenige Zeilen.
Ob das unbedingt übersichtlich ist, ist auch noch fraglich.
Viel Erfolg, Uwe
Uwe schrieb:
>>weil die FFs dort als NOP interpretiert werden> Ist das wirklich so, weil NOP =$0000 und nicht $FFFF.> Das könnte eher SBRS sein.
$FFFF ist ein illegaler Opcode, und solche werden wie ein NOP behandelt.
Hi
>Man denkt, ein C-Programm würde noch langsamer und größer. Aber das>Gegenteil ist der Fall, durch die Strukturierung werden Programme in der>Regel schneller und kleiner.
Was hat Struktorierung mit der Programmiersprache zu tun? Ich wette, das
man in C genau so unstrukturiert programmieren kann, wie in Assembler.
Und der bisher hier veröffentlichte disassemblierte C-Code lässt mir
jedes mal die Nackenhaare hochstehen.
MfG Spess
@ Hazeh Zimmerer
Werde ich testen.
@ Peter Dannegger
>Ak Tronik schrieb:>> Alle rjmp in jmp ändern habe ich verworfen weil ich dann auch alle rjmp>> PC+X mit ändern muss. Da ist der nächste Fehler schon vorprogrammiert.>Warum?>Traust Du dem Assembler nicht?>Glaub mir, der kann besser rechnen als Du.>Mach es!
Also, es erscheint mit logisch, daß das nicht funktioniert ohne von Hand
nachzuarbeiten weil rjmp aus einem Wort und jmp aus zwei Worten besteht.
1
lds r16,s_ParaFlags
2
sbrs r16,ParaProdEn
3
rjmp ProdOff
4
5
sbrc w_FallA,A_GateProd
6
rjmp PC+4
7
sbrc w_FallA,A_Prod
8
rjmp PC+2
9
rjmp PC+7
10
11
sbrc w_DeBoInPortA,A_GateProd
12
rjmp PC+5
13
sbrc w_DeBoInPortA,A_Prod
14
rjmp PC+3
15
rcall SetShiftRegProd
16
....
17
....
>Ohne Dich kritisieren zu wollen, die 10kB Assembler lassen vermuten, daß>der Code wenig strukturiert ist, d.h. viele ähnlich Programmteile>hintereinander enthält (der gefürchtete Spaghetticode).
Immer her mit konstruktiver Kritik.
Ich habe eine sehr kleine Hauptschleife, die die in den kleinen ISR
gesetzten Flags auswertet und in Abhängigkeit der Flags, mit rcall eine
größere Hauptfunktion aufruft. Die Hauptfunktion ruft weitere Funktionen
mit rcall auf die wiederum mit rcall weitere Funktionen aufrufen.
Letztendlich geht es mit ret in die Funktion zurück die aufgerufen hat.
Hier und da ist aber auch aus Geschwindigkeitsgründen Spaghetticode
vorhanden um rcall und ret einzusparen.
@ Uwe
>Ob dein Code spinnt oder dein µC musst du doch raus finden können.
Hab den µC aus Verzweiflung ausgetauscht( geht erheblich schneller als
debuggen)
>Wie wäre es mit einem>.org 0x2774
Werde ich testen.
MfG
Ak Tronik
>Die Hauptfunktion ruft weitere Funktionen>mit rcall auf die wiederum mit rcall weitere Funktionen aufrufen.
rcall hat doch dieselben Einschränkungen wie rjump.
Gibt es da sowas wie eine Mauer wenn man von Code unterhalb
8kB auf Code oberhalb 8kB aber innerhalb 8kB relativ springt?
Kein Wunder das ich AVR fast nur in C programmiere.
Da gibt es noch anderen Deppenkram bei Assembler für AVR.
Hi
>Kein Wunder das ich AVR fast nur in C programmiere.>Da gibt es noch anderen Deppenkram bei Assembler für AVR.
Wozu aufregen. Unzulässige Sprungweiten bei 'rjmp'/'rcall' erzeugen eine
Fehlermeldung.
Wenn ich hier so lese, scheint C auch genug Deppenkram bereitzuhalten.
MfG Spess
Ak Tronik schrieb:
> Also, es erscheint mit logisch, daß das nicht funktioniert ohne von Hand> nachzuarbeiten weil rjmp aus einem Wort und jmp aus zwei Worten besteht.>>
1
> rjmp PC+2
2
> rjmp PC+7
3
>
Da haste recht, dann stimmen die Zahlen nicht mehr.
Ich hatte nicht erwartet, daß jemand keine Labels benutzt, sondern die
Sprünge händisch ausrechnet.
Beim Asssembler2 braucht man das auch nicht, der kann lokale Labels in
Macros.
Peter
>Wenn ich hier so lese, scheint C auch genug Deppenkram bereitzuhalten.
Sicher, wenn man es nicht kann;)
Auf jeden Fall spart C ne Menge Arbeit wenn man z.B.
Code für das SPI Modul schreibt der dann auch auf ATMega8
UND ATMega644 ohne Anpassungen läuft. In Assembler ne echte
Krücke.
Hi
>Auf jeden Fall spart C ne Menge Arbeit wenn man z.B.>Code für das SPI Modul schreibt der dann auch auf ATMega8>UND ATMega644 ohne Anpassungen läuft. In Assembler ne echte>Krücke.
Da der AVR-Assembler bedingte Assemblierung beherrscht, ist das
eigentlich kein Problem. Habe ich in Assembler wahrscheinlich genau so
schnell realisiert, wie du in C.
MfG Spess
>>Auf jeden Fall spart C ne Menge Arbeit wenn man z.B.>>Code für das SPI Modul schreibt der dann auch auf ATMega8>>UND ATMega644 ohne Anpassungen läuft. In Assembler ne echte>>Krücke.>Da der AVR-Assembler bedingte Assemblierung beherrscht, ist das>eigentlich kein Problem. Habe ich in Assembler wahrscheinlich genau so>schnell realisiert, wie du in C.
Ich schreib einfach:
while(! ( SPSR & (1<<SPIF) ) );
Lass den Compiler doch die Drecksarbeit machen.
Hi
>ch schreib einfach:>while(! ( SPSR & (1<<SPIF) ) );>Lass den Compiler doch die Drecksarbeit machen.AVRs sind aber nicht in allen Beziehungen so einheitlich. Wenn du z.B.
eine UART im SPI-Modus benutzen willst dann ist das schon nicht mehr so
einfach. Dann will der Compiler das auch schon etwas genauer wissen.
MfG Spess
>AVRs sind aber nicht in allen Beziehungen so einheitlich. Wenn du z.B.>eine UART im SPI-Modus benutzen willst dann ist das schon nicht mehr so>einfach. Dann will der Compiler das auch schon etwas genauer wissen.
Ein Punkt für dich;)
Den Bockmist hat Atmel verbrochen.
TIMSK, TIMSK0, TIMSK1
Keine klare Linie in der Namensgebung.
Die würde ich mir für die Zukunft wünschen.
Hi
>Den Bockmist hat Atmel verbrochen.>TIMSK, TIMSK0, TIMSK1>Keine klare Linie in der Namensgebung.>Die würde ich mir für die Zukunft wünschen.
Bitte keine Ausreden. Ich habe nichts gegen C. Ich habe nur etwas gegen:
-Gleichsetzung der Universalität im PC- und µC-Bereich
-Arrogante C-Programmierer
MfG Spess
@ Peter Dannegger,
>Ich hatte nicht erwartet, daß jemand keine Labels benutzt, sondern die>Sprünge händisch ausrechnet.
Ne, ne, bei über 5000 Programmwörtern benutze ich über 200 Labels und
knapp 180 rjmp PC+2 bis PC+7.
Für kleine Sprünge benutze ich gerne PC+x und springe so z.Zt. nicht
weiter als 7 Wörter. So bleiben diese Sprünge noch übersichtlich.
Dazu muß ich mir nicht noch 180 sinvolle und funktionsbezogene Labels
ausdenken.
MfG
Ak Tronik
>Bitte keine Ausreden. Ich habe nichts gegen C. Ich habe nur etwas gegen:>-Arrogante C-Programmierer
Ich bin kein arroganter C-Programmierer.
Ich habe Z80, 8051, 68000er, PICs und AVRs in Assembler programmiert.
Irgendwann sucht man mal den kleinsten gemeinsamen Nenner.
Das war halt C. Es macht einfach keinen Spaß jedesmal das Rad
neu zu erfinden.
Ich kann auch Fortran, Pascal, das alte DOS-Basic, Visual Basic,
Visual C++, Turbo-C++.
Bascom, Cobol und Forth hab ich noch nicht nicht gemacht. Vieleicht
hab ich da auch noch mal etwas Zeit für;)
Hi
>Dazu muß ich mir nicht noch 180 sinvolle und funktionsbezogene Labels>ausdenken.
Immerhin einfacher, als jedesmal neu zu rechnen. Wo hast du denn das
gelernt.
In dem Fall verstehe ich sogar die Vorbehalte von Benutzern anderer
Programmiersprachen, das ASM-Programme schlechter zu verstehen und zu
warten sind. Ich bin notorischer Assemblerprogrammierer, aber das ist
Schwachsinn.
MfG Spess
@ spess53
Die Sprünge sind sehr kurz. Was gibt es an an PC+3 zu berechnen?
Das sieht man doch.
Wenn ich ne 5 würfel dann zähle ich doch auch nicht die Augenzahl.
MfG
Ak Tronik
Hi
>Ich bin kein arroganter C-Programmierer.
Hast du dich angesprochen gefühlt? Das war von mir aus ganz allgemein
gemeint.
>Ich habe Z80, 8051, 68000er, PICs und AVRs in Assembler programmiert.>Irgendwann sucht man mal den kleinsten gemeinsamen Nenner.>Das war halt C. Es macht einfach keinen Spaß jedesmal das Rad>neu zu erfinden.
Erzähl mir aber jetzt nicht, das du ein Programm für AVR schreibst, das
auf allen anderen ohne Änderung läuft.
MfG Spess
Hi
>Die Sprünge sind sehr kurz. Was gibt es an an PC+3 zu berechnen?>Das sieht man doch.>Wenn ich ne 5 würfel dann zähle ich doch auch nicht die Augenzahl.
Nur mal so: Hast du ein Problem, oder ich.
MfG Spess
Hallo,
Ak Tronik schrieb:
> @ spess53>> Die Sprünge sind sehr kurz. Was gibt es an an PC+3 zu berechnen?> Das sieht man doch.> Wenn ich ne 5 würfel dann zähle ich doch auch nicht die Augenzahl.
Viel Spaß beim Debug mit dieser Methode...
Ichschreibe fast nur Assembler, auf die Idee, ein paar Label zu sparen
und dafür bei JEDER Änderung an solchen Stelleb nachdenken zu müssen,
was ich jetzt korrigieren muß, weil ich mal schnell ein ldi
data,testdaten oder ein lds data,testdaten einfüge...
Die Fehler, die dazustande kommen, möchte ich in meinen Programmen nicht
suchen wollen.
Solche Label heißen bei mir wie der Programmteil + laufende Nummer.
Mögliche Dublikate beim Test mault dann schon der ASM an.
Gruß aus Berlin
Michael
Ich schrieb:
>Die Sprünge sind sehr kurz. Was gibt es an PC+3 zu berechnen?
OK, ich ziehe diese Aussage bedingungslos zurück.
Die PC+Sprungweiten-Methode sehe ich nun als größte potentielle
Fehlerquelle, auch wenn sie maximal 7 Wörter weit sind.
So, dann werde ich mal 180 Labels setzen. Auch in der Hoffnung den
Fehler auf diesem Weg zu finden.
Benutzt ihr noch nicht mal PC+2 ?
MfG
Ak Tronik
Ak Tronik schrieb:
> Benutzt ihr noch nicht mal PC+2 ?
Ich nutze immer nur Labels, selbst für so Sachen wie
hier: rjmp hier
Das macht meiner Meinung nach den Code besser lesbar. Ansonsten kann man
durchaus auf die Idee kommen, obiger Code wäre identisch mit rjmp PC+0,
also quasi ein auf der Stelle stehen bleiben (da man vergessen hat, dass
der Befehl eigentlich PC=PC+k+1 macht).
Auch kann man sich sehr schnell verzählen oder sonstige Fehler machen
wenn man z.B. rjmp durch jmp ersetzt, was ja 2 Wörter groß ist.
ELM-Chan verwendet die PC+k Schreibweise in seiner Software
(http://elm-chan.org/cc_e.html), das hat mich einiges an Zeit und Nerven
gekostet diese an meine Bedürfnisse anzupassen.
Sooooo, ich hab den Fehler endlich nach Stunden gefunden :-)
1
cpi r16,2
2
brlo PC+4
3
sbr w_MakroByte,1<<ErrPPClockGLumi
4
sbr w_Flag2,1<<ErrToSend
5
call DelShiftReg
6
7
lds r16,s_CntGateLumi
8
cpi r16,2
Die Zeile call DelShiftReg war zuvor rcall DelShiftReg. Habe sie
abgeändert weil rcall nicht mehr ausreichte. brlo PC+4 hätte ich dann in
brlo PC+5 abändern müssen oder noch besser so:
1
cpi r16,2
2
brlo CntClockOK
3
sbr w_MakroByte,1<<ErrPPClockGLumi
4
sbr w_Flag2,1<<ErrToSend
5
call DelShiftReg
6
7
CntClockOK: lds r16,s_CntGateLumi
Wie geschrieben werde ich alles labeln.
Vielen Dank an Euch für die zahlreichen Tipps, die mich darauf gebracht
haben.
MfG
Ak Tronik
Ak Tronik schrieb:
> Die Zeile call DelShiftReg war zuvor rcall DelShiftReg. Habe sie> abgeändert weil rcall nicht mehr ausreichte. brlo PC+4 hätte ich dann in> brlo PC+5 abändern müssen
Wow.
Der praktische Beweis, dass diese 'Selbstrechnerei' eine einzige
Fehlerquelle ist.
Was besseres konnte dem Forum gar nicht passieren :-)
> oder noch besser so:>
1
> cpi r16,2
2
> brlo CntClockOK
3
> sbr w_MakroByte,1<<ErrPPClockGLumi
4
> sbr w_Flag2,1<<ErrToSend
5
> call DelShiftReg
6
>
7
> CntClockOK: lds r16,s_CntGateLumi
8
>
Ich finde auch den Nebeneffekt nicht zu verachten.
Beim lds steht ein Label und das steht dort nicht ohne Grund.
Also wird es wohl einen jmp oder call geben, der hier mündet. Wenn
hinter diesem Label Änderungen passieren muss man daher auch immer im
Hinterkopf haben, dass einen 'Aufrufer' gibt, der von bestimmten
Voraussetzungen an dieser Stelle ausgeht und man kann nicht einfach
ändern wie man lustig ist. Zusätzlich ermöglicht mir das Label dann auch
noch das Finden, wo denn der Aufruf/Jmp herkommt.
@ Karl heinz Buchegger
>Was besseres konnte dem Forum gar nicht passieren :-)
Und was schlimmeres mir nicht ;-)
Die Fehlersuche beläuft sich auf 12-14 Stunden effektiv.
Das war die längste Fehlersuche die ich hatte. Meine vorherigen
ASM-Programme waren allerdings auch weit unter 5000 Instruktionen.
Danke noch mal am das Super-Forun hier !!!
MfG
Ak Tronik