Forum: Mikrocontroller und Digitale Elektronik asm optimierung


von Uwe H. (blackboxv)


Angehängte Dateien:

Lesenswert?

Hallo Werte Nutzer,
ich bin immer noch an meiner Schleife und weil ich "seinerzeit" mit dem 
Z80ig geprogt habe. hab ich mal folgendes ausprobiert.
Ich wollte mal wissen, wie Atmel Studio die in den 2 Anhängenden zu 
sehen interpretiert
Wenn man Speicher sparen muss ist es, denke ich interessant.
Ich hab den Code im Internet gefunden und will lernen um dieses kleine 
Programm zu optimieren.

Gruß Uwe

von Uwe H. (blackboxv)


Lesenswert?

Hi ,
hab ich es optimiert ?

von Ulrich H. (lurchi)


Lesenswert?

Bitte Dateiformate beachten - ASM Sourcecode als Jpeg ist nun wirklich 
nicht die richtige Wahl.

Wenn es schon eine Bildschirm-foto sein muss, dann eher als .PNG , das 
wird kleiner.

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Wir sind alle stolz auf dich und deinen großen Bildschirm und auch dass 
Du nebenher Filmchen schaust.

von Uwe H. (blackboxv)


Lesenswert?

Hallo Thomas, es sind 2 Monitore.
Die sind über 5 Jahre alt.
also angeben ist unangebracht
liebe grüße Uwe

von Peter R. (pnu)


Lesenswert?

Die einzig sinnvolle Optimierung besteht darin, anstelle einer/mehrerer 
Schleifen im Programm den Timer des Kontrollers zu benutzen.

Zeitverzögerung mittels Schleife ist so unrationell, dass jede 
Optimierung sinnlos ist.

Das Problem besteht nicht im Speichersparen, sondern im Zeitsparen. 
Solange die Zeitschleife im Hauptprogramm abläuft, können die andren 
Befehle des Hauptprogramms nicht ausgeführt werden. Wenn man dem Timer 
das Zeitzählen überlässt, ist in der Zwischenzeit zwischen den Ints der 
Kontroller für die Ausführung der andren Befehle des Programms frei.


Sinnvolles Verfahren geht so voran:

Timer so programmieren, dass bei jedem Timer-Überlauf ein Int erfolgt. 
(z.B. jede ms)
In Int-Routine eine Zahl(z.B. r16) inkrementieren, prüfen, ob diese 
einen passenden Wert erreicht hat (z.B. 200) und dann z.B.die LED Ein- 
oder Ausschalten. Mit dem reti ist dann die int-Routine zuende und der 
Kontroller ist wieder für das Hauptprogramm frei. Bei 16MHz Takt, kann 
der AVR dann zwischen zwei Ints fast 16000 Befehle ausführen, die bei 
Schleifentechnik blockiert wären.

Leider ist die primitive delay(...) Schleife Bestandteil vieler 
Programmiersprachen und auch eine der ersten Übungen in Assembler - aber 
man sollte sie gleich vergessen, sobald man mit dem Timer arbeiten kann.

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

Deine Monitore interessieren den Gasmann. Aber ist es so schwer zu 
begreifen, das Screenshots das ungeeignetste Mittel der Darstellung von 
Quelltexten ist.

MfG Spess

von Dietrich L. (dietrichl)


Lesenswert?

Peter R. schrieb:
> In Int-Routine eine Zahl(z.B. r16) inkrementieren, prüfen, ob diese
> einen passenden Wert erreicht hat (z.B. 200)

So finde ich es deutlich universeller:
- Der Anwender startet die Zeit durch Laden einer Variablen.
- Die ISR zählt Variable runter wenn ungleich 0.
- Der Anwender fragt die Variable auf 0 ab und macht die Aktion.
Vorteil: der Anwender kennt seine gewünschte Zeit, mit der er die 
Variable läd, und was danach zu tun ist. Die ISR muss davon nichts 
wissen.

Gruß Dietrich

von Yalu X. (yalu) (Moderator)


Lesenswert?

Das linke Programm ist 58, das rechte (optimierte) 52 Bytes groß. Du
hast die Verzögerungsschleife ausgelagert und damit die eine Kopie davon
eingespart. Auf der anderen Seite brauchst du zusätzlich zwei RCALLs und
einen RET, so dass sich der Gewinn in Grenzen hält. Aber immerhin.

Es gibt aber noch mehr zu optimieren:

- Wozu sind die drei NOPs gut? Lass sie weg.

- DDRB wird mehrfach beschrieben. Einmal reicht.

- Die äußere Zählschleife zählt aufwärts? Lässt du sie abwärts bis 0
  zählen, sparst du den CPI ein.

- Um in PORTB ein einzelnes Bit zu setzen und wieder zu löschen, kannst
  du SBI bzw. CBI nehmen. Du sparst damit zwei LDIs ein.

- Da du den ATtiny13 verwendest: Der hat das Pin-Toggle-Feature, bei dem
  du mit einem SBI auf PINB ein einzelnes Bit in PORTB abwechselnd
  setzen und löschen kannst. Da das Setzen und Löschen so mit dem
  gleichen Code geschieht, reicht es, ihn einmal hinzuschreiben und
  dafür 20- stat 10-mal auszuführen. Dadurch brauchst du auch die
  Verzögerungsschleife nur einmal und kannst sie folglich wieder direkt
  in die Hauptschleife integrieren, wodurch die RCALLs und der RET
  wegfallen.

- Die Verzögerungsschleife enthält zwei ineinanderverschachtelte
  Schleifen um eine 16-Bit-Zähler zu realisieren. Der ATtiny hat auch
  16-Bit-Additions- und -Subtraktionsbefehle (ADIW und SBIW), die auf
  Registerpaaren operieren. Damit kannst du die 16-Bit-Zählung
  vereinfachen.

Wenn du alles oben Geschriebene anwendest, bleibt ungefähr folgendes
Progämmchen übrig (hab's aber nicht getestet):
1
  ldi  r21,0x08
2
  out  DDRB,r21
3
  ldi  r21,20
4
loop1:
5
  sbi  PINB,3
6
  ldi  r24,0x41
7
  ldi  r25,0xbf
8
loop2:
9
  sbiw r25:r24,1
10
  brne loop2
11
  dec  r21
12
  brne loop1
13
loop3:
14
  rjmp loop3

Die 58 bzw. 52 Bytes von oben sind damit auch 22 geschrumpft.

Noch kürzer geht es unter Zuhilfenahme des Hardware-Timers des ATtiny13,
aber nicht (wie von einigen vorgeschlagen) mit einem Interrupt, sondern
direkt mit der Output-Compare-Unit. Das Programm besteht dann nur noch
aus der Initialisierung von ein paar I/O-Registern. Das müsste bit etwa
10 Bytes hinzubekommen sein.

Edit: In den 10 Bytes ist die Überprüfung der 10 Blinkperioden noch
nicht anthalten. Damit wird der Code dann doch wieder etwas länger.

: Bearbeitet durch Moderator
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

Hallo,

schön das sich wieder jemand für die AVR-Assemblerprogrammierung 
interessiert. Hoffe Du bleibst eine zeitlang dabei und nicht wie viele 
Studenten usw. die mal für den Unterricht hier ein paar Fragen stellen 
und man dann nichts mehr von Ihnen liest.

Peter R. hat schon recht. Irgendwie lernen wir Anfänger diesen 
Schleifenverzögerungsquatsch und denken, das man so programmieren 
würde, was natürlich blödsinn ist. PeDa ( Peter Dannegger ) ist Dir 
sicher ein Begriff und der schrieb einmal das er fast ausschließlich in 
jedem Programm mit Timerinteruppts arbeitet, also mit einer im 
Hintergrund laufenden Zeitbasis.

Wenn ich Dich richtig verstehe, geht es Dir darum zu erkennen, ob Du 
Programmspeicher gespart hast und nutzt dafür ein weiteres Programm.
Aber das AVR-Studio zeigt Dir die Sache nach dem Assemblieren noch 
besser an. Das Buildfenster must Du dazu nach oben " aufziehen ".
Im Anhang ist mal ein Screeshot von einem kürzlich von mir bearbeiteten 
Programm, wo der Programmspeicher zu 99,6% voll ist. Da muss man schon 
mächtig viele Zeilen ( hier ca. 4785 Zeilen bei 8KB Speicher )schreiben 
um so weit zu kommen.

Erst wenn Du mal in solch eine predulie kommst solltest Du Dir Gedanken 
über den Speicherplatz machen. Voher kann ich Dir nur raten sich daran 
zu halten was in diesm File steht :

Das ist das ZIP-File ( *lcdtrtc.zip* )

file:///E:/Projekte/AVR-Uhr/INDEXG.HTM

das man hier findet :

Beitrag "Zeit + Temperatur auf LCD mit AVR"

Da sind sehr nützliche Tipps vom Profi drin ;-)
Dazu die *INDEXG.HTM* zuerst öffnen bzw. doppelklicken.

Auch Hannes Lux seine Programme solltest Du Dir mal reinziehen,
die zwar auch heftig, aber so in etwa geht Assemblerprogrammierung.

Und hier noch was Aufbauendes :

http://www.avr-asm-tutorial.net/avr_de/beginner/


Peter R. schrieb:
> Die einzig sinnvolle Optimierung besteht darin, anstelle einer/mehrerer
> Schleifen im Programm den Timer des Kontrollers zu benutzen.
>
> Zeitverzögerung mittels Schleife ist so unrationell, dass jede
> Optimierung sinnlos ist.
>
> Das Problem besteht nicht im Speichersparen, sondern im Zeitsparen.
> Solange die Zeitschleife im Hauptprogramm abläuft, können die andren
> Befehle des Hauptprogramms nicht ausgeführt werden. Wenn man dem Timer
> das Zeitzählen überlässt, ist in der Zwischenzeit zwischen den Ints der
> Kontroller für die Ausführung der andren Befehle des Programms frei.
>

Bis dann
          Bernd_Stein

: Bearbeitet durch User
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
Noch kein Account? Hier anmelden.