Az EP gépi kódú programokban láttatok-e már olyat, hogy a dinamikus változók tárolására a vermet használja, méghozzá oly módon, hogy az IX vagy IY regiszterek a báziscímek, és ahhoz képest helyezkednek el változók?
Szerintem ez inkabb magasabb szintu programnyelveknel szokas, bar nyilva jol jon pure asm-ban is, ha olyan trukkos dolgok kellenek mint rekurzio stb. Peldaul a mostani jatszadozasom, ahol az sdcc C fordito (ami tud Z80-ra kodot generalni) kepes legyen EP-re alkotni valamit: ott egy primitiv programnak (mondjuk hasznaljon valami chat/string output-ot meg olvasson billenyuzetet) azt varja, hogy a putchar es getchar rutint implementald, ha ez megvan akkor std printf() stb menni fog csupan ezzel a ket fuggvennyel, amit neked kell megirnod viszont. No, ezt persze assembly-ben csinalom, EXOS hivasokkal, amde itt pl a C fordito miatt tartanom kell magamat a konvekciohoz: azaz pl putchar eseten a kiiradno char a veremben lesz, ami C szinten kb igy definialhato: void putchar (char data). (visszateresi ertek - ami mondjuk putchar-nal nincs, de getchar()-nal igen - meg siman pl az L regiszterben kell atadni, felteve ha az sima byte-ban reprezentalhato ertek.
...stb...
LD SP,IX ; A hívás előtti stack visszaállítása
POP IX ; A hívás előtti referenciapont visszaállítása
Na egen, pl az altalam implementalt putchar() fuggveny, amit aztan sdcc forditott cucc stdio-ja kepes hasznalni:
; THIS IS putchar() function for the C runtime
.globl _putchar ; C syms are underscored in assembler
_putchar:
push ix ; SDCC uses IX to access params in stack. you must save it
ld ix,#0 ; ... and use ix=sp since Z80 lacks of sp relative addressing
add ix,sp
ld b,4(ix)
ld a,#MY_VIDEO_CHANNEL
EXOS 7
pop ix
ret
Valojaban itt az 'add' azert van igy, mert kiserleteztem a dologgal, es nem akartam az IX+...-nel offset-eket mindig atirni, van ahol meg tobb parameter is van. A +4 se feltetlen igaz a fenti megjegyzessel, azert +4 (es nem +2, a viszzateresi ertek is a stack-ban van mar), mivel a push-al mi is berakunk egy word-ot elotte. Az elejen egy kicsit bele is keveredtem, azert most a mostani kodom kisse kusza tobb helyen is. Az assembly formatum meg fura, mert az sdcc assembler-e igy tudja, azaz pl (ix+4) helyett 4(ix) kell neki.
Amugy van ezzel kapcsolatban azert egy erdekesseg. Alapbol az sdcc is - ahogy te is hozol peldakat, illetve en is irtam - az IX regisztert hasznalja kvazi stack pointer relativ cimzes megvalositasahoz. Amde, ez nem feltetlenul optimalis. Ugyanis kisse "lassu", ha jol saccolom fejbol valami 18 (? vagy 19) ciklus. Ellenben az ld a,(hl) az pl csak 7, igaz nem tudsz offset-et, de meg ha inc-et hasznalod mindig utana (6 ciklus), a ketto meg mindig gyorsabb! Es raadasul nem kell pop/push sem nagyon mert a hl-bol kivonsz a vegen. Ez ranezesre csunyabbnak, es korulmenyesebbnek tunik, de bizonyos felhasznalasi minta mellett meg mindig gyorsabb. Talan ezert is van, hogy ujabban az sdcc-ben talaltam, miszerint az un peephole optimalizatora atirja a C fordito altal generalt assembly forraskodban ilyenre a cuccot es utana ereszti ra csak az assemblert.
Osszefoglalva: imho egy asm only projecnel a stack allando hasznalata parameteratadasra (kovetkezetesen, mindig) nem feltetlenul a leggyorsabb, amde magasabb szintu programozasi nyelvek eseten kevesbe kikerulheto ...