Forum: Projekte & Code PUSH/POP/MACRO für AVR in Assembler


von Dagobert (Gast)


Lesenswert?

.MACRO  PUSHER
  push  ZL
  push  ZH
  rcall pu
pu:  pop   ZH;l
  pop   ZL;h
  rjmp  @0
.ENDMACRO


.MACRO  POPER
  rcall po
po:  pop  ZH;l
  pop  ZL;h
  rjmp @0
  pop  ZH
  pop  ZL
.ENDMACRO


meinelieblingspushfunktion1:

  push meinlieblingsregister1
  push meinlieblingsregister2
  push meinlieblingsregister3
  ;etc

  ;Muss hier immer stehen:
  ;-----------------------
  adiw ZL,3
  push ZL
  push ZH
  ret

meinelieblingspopfunktion1:
  pop  meinlieblingsregister3
  pop  meinlieblingsregister2
  pop  meinlieblingsregister1
  ;etc

  ;Muss hier immer stehen:
  ;-----------------------
  adiw ZL,3
  push ZL
  push ZH
  ret



Aufruf dann in einer Funktion:

Funktion:
PUSHER meinelieblingspushfunktion1:

;Code

POPER  meinelieblingspopfunktion1:
ret


Sinn macht es natuerlich nur, wenn man mehr als 6 Register weglegen 
will.
Bei weniger ist der Overhead zu groß, zumindest muß man aber nicht so 
viel
schreiben.

Bei sehr großen Programmen, die vielleicht schon Speicherplatzprobleme 
haben,
könnten diese Makros vielleicht wieder einige Bytes einsparen.

von Ludger (Gast)


Lesenswert?

Ich nutze etwas aehnliches, jedoch spare ich beim Ruecksprung noch durch 
einen indirekten Sprung :-)

ijmp           ; Return address is in Z and so this ijmp returns from 
subroutine

von Dagobert (Gast)


Lesenswert?

ich bin einer der Gelegenheitsprogrammierer, die noch ab und zu wieder
ins instruction manual schauen müssen ;-)
Danke für den Hinweis :-)

von Joerg W. (joergwolfram)


Lesenswert?

In meinen aktuellen Programmen nutze ich ein ähnliches Verfahren, wobei 
R0/R1 immer nur lokal genutzt werden, so z.B, um alle 3 Pointer zu 
sichern / zu restaurieren:
1
push_ptr: pop   R0          ;Return-Adresse merken
2
          pop   R1
3
          push  ZH
4
          push  ZL
5
          push  YH
6
          push  YL
7
          push  XH
8
          push  XL
9
          push  R1
10
          push  R0
11
          ret
12
13
pop_ptr:  pop   XL
14
          pop   XH
15
          pop   YL
16
          pop   YH
17
          pop   ZL
18
          pop   ZH
19
          ret
Im Unterprogramm sieht das dann so aus:
1
subr:     call  push_ptr
2
          ...
3
          jmp   pop_ptr
Wenn man oft die gleichen Register sichern und wieder restaurieren muß, 
spart das eine ganze Menge Speicherplatz, allerdings zu Lasten längerer 
Ausführungszeit.

Jörg

von Dagobert (Gast)


Lesenswert?

Ich war blind, es geht ja noch einfacher:

.MACRO  PUSHER
  push  ZL
  push  ZH
  rcall @0
.ENDMACRO


.MACRO  POPER
  rcall @0
  pop  ZH;l
  pop  ZL;h
.ENDMACRO


meinelieblingspushfunktion1:
  pop  ZH;l
  pop  ZL;h
  ;-----------------------

  push meinlieblingsregister1
  push meinlieblingsregister2
  push meinlieblingsregister3
  ;etc

  ;Muss hier immer stehen:
  ;-----------------------
  ijmp


meinelieblingspopfunktion1:
  pop  ZH;l
  pop  ZL;h
  ;-----------------------

  pop  meinlieblingsregister3
  pop  meinlieblingsregister2
  pop  meinlieblingsregister1
  ;etc

  ;Muss hier immer stehen:
  ;-----------------------
  ijmp

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.