( bucko | 2016. 07. 13., sze – 11:28 )

Van pár új dolog ami esetleg téged is érdekelhet.
Nem igazán. Elkerülte a figyelmedet, hogy folyamatosan a snapshot-ot használtam. ;)
Sőt, közben a frissített doksit is olvasgattam.
Ráadásul nem csak tesztelgettem, hanem ezzel dolgozok.
Igazán nem mondhatod, hogy nem bízom a munkádban!

Ilyen például az hogy egy call után törlöm a bank hozzárendelést, mivel a jó ég tudja hogy mit művel a szubrutin.
Igen, ezeket olvastam a doksiban, de anélkül is tudtam, mert ez a helyes megoldás.
Most, amikor elkészült a release, és kicsit pihentél, megnézhetnéd újra miket írtam erről. (pl. #pragma isolated_call) Persze asm esetén elég ciki lenne minden call, stb. elé írni a deklarációt. Nem látszana a kód!

Ezt végül is megcsinálhatod makrókkal is, vagy jobban szeretnéd ha a gpasm segítene a változók kezelésében? ;-)
Ha az __ACTIVE_BANK_ADDR törlődik pl. call után, akkor nem tudom megakadályozni a következő felesleges üzenetet vagy hibát!

#define NOTHING __BANK_INV
        call Subr
;jelenlegi megoldás
        __ACTIVE_BANK_ADDR=NOTHING
;helyette ezt kellene tennie a fordítónak (pl.) call után
if ( __ACTIVE_BANK_ADDR_GLOBAL == NOTHING )
        __ACTIVE_BANK_ADDR=NOTHING
endif
;egyéb esetekben ...,b esetén
if ( __ACTIVE_BANK_ADDR == NOTHING )
        __ACTIVE_BANK_ADDR = __ACTIVE_BANK_ADDR_GLOBAL
endif
;és ha az is NOTHING, akkor jöhet az üzi ;)

Ezt nem lehet makróval megcsinálni!
(Ez nem teljesen igaz. Lehetne kapcsolgatni az errorlevel-t. Ennek az őszinte megtételéhez közel annyi vizsgálatot kellene megtenni, mint a fordító. Tehát ez sem jó!)
Lehetne egy pótvizsgálat:
- a call előtt elmenteni az __ACTIVE_BANK_ADDR értékét
- a call utáni vizsgálat összehasonlítja a mentett és és globális értéket
- eltérés esetén üzenet => Erre csak akkor van szükség, ha nem a fordító kezeli az assume direktívát.
Belegondolva, elegendő lenne, ha a fordító kezelné az assume direktívát - ekkor nincs szükség globális változóra.
Miről is beszélek? A program úgy készül, hogy írása közben próbálom minimalizálni a bármilyen üzenetek számát. Ha a fordító üzen, hogy nem biztos a helyes címzésben, akkor odaírok egy assume-t. Ezzel megszűnik az üzenet. Ha valahol nem jól állítom be a címzést, akkor átvertem a fordítót. Hazudtam, de ez az én büntetőjogi felelősségem. ;)
Ezzel szemben, jelenleg a fordító feltételez, és ezzel elromlik a címzés, amivel további hibás üzenetek keletkeznek. Ez azért rosszabb, mert csak újabb utasítással (+kód) tudom feloldani. Az 1200db üzenetből kiindulva, közel ennyi helyen kellene módosítanom a kódot, hogy minden esetben elmagyarázzam a helyes címzést!

A proc-endp hiánya nem annyira meglepő. Az x86-hoz képest ezek a processzorok a stack frame-et csak szoftverből tudják emulálni. No, ez sem meglepő, mert inkább vezérlésre készültek, mint magasszintű struktúrált kód végrehajtására. A procedúrát nézve alapszabály az egyetlen be- és kilépési pont, azaz a befejezéshez el kell ugrani a procedúra végén levő stack frame takarító kódig. Csak utána jöhet a return.
Vezérlésnél az ember logikus sorrendben végzi a vizsgálatokat, igyekezve minél előbb visszatérni a hívásból. Így ki lehet hagyni az adott helyzetben felesleges kódot, amit azért kell megtenni, mert nincs idő.

Ugyan ez igaz a stack frame/lokális változók kezelésére. Pl. a C-ben megírt USB drivert dolgoztam át úgy, hogy majdnem az összes változót kitöröltem. :) A paraméterek átadásához "emulálom" a sokregiszteres processzort, aminek van pl. R0..R5 scratchpad regisztere - az access területen. Ehhez meg kellene egy időtrabló pusha utasítás interrupt esetére. Ezért interrupt alatt - ahol a kód jó része fut - az r0..r5 regisztereket használom - esetleg az egyetlen bank területen, mert az acces már elfogyott. Bizonyos szemszögből ez pazarlónak tűnhet, de ez a konvenció gyorsabb és rövidebb kódot eredményez kevesebb memória felhasználásával.

Néha jól jönne egy blokk lezárás.
No, igen. Mégsincs probléma ezzel. Ugyanaz a szituáció, amikor x86-ra nem struktúrált programot írsz. A proc és endp között olyan kód van, amikor "nem csak a kijáraton lehet kihajtani".
Hova helyeznéd a blokkhatárt a proc1 és proc2 esetén, ha az alábbi végrehajtási sorrendek lehetségesek?
- call proc1 -> return
- call proc1 -> jump proc2 -> return
- call proc2 -> return