32. Prekladač action26
Doteraz si z prekladača používal tri veci: action26 program.act, --sim a --run. Táto kapitola prejde ostatné voľby. Od tejto kapitoly ide o veci, ktoré pôvodný Action! na Atari nemal.
Tvar príkazu
action26 program.act [voľby]Voľby sa píšu za meno programu, v ľubovoľnom poradí. Úplný zoznam vypíše:
action26 --helpVýstup
| Voľba | Čo robí |
|---|---|
-o súbor | meno výsledného súboru; bez nej je to meno programu s príponou .xex |
--listing súbor | výpis preloženého programu: adresy, bajty a inštrukcie procesora |
--asm súbor | zdroják v assembleri 6502, z ktorého sa dá program zostaviť znova |
--map súbor | zoznam mien s adresami |
--lab súbor | zoznam mien pre ladiace nástroje emulátorov |
--memory | po preklade vypíše, koľko pamäte program zaberá a koľko ešte ostáva voľnej, vrátane pamäte pod ROM |
--memory-map | to isté, ale s výpisom každého kúska pamäte po adresách |
--reserve od-do | pamäť, ktorú program používa len za behu a nie je v súbore (napríklad buffer obrázka $A100-$B7BF); dá sa zadať viackrát |
--mem-lo adresa, --mem-top adresa | v akom rozsahu pamäte sa voľné miesto počíta (predvolene $0700 až $BBFF) |
--org adresa | adresa, od ktorej program v pamäti začína (predvolene $2000) |
action26 hello.act -o HELLO.XEX --listing hello.lstKoľko pamäte ešte ostáva
Pri väčšom programe, napríklad textovke, sa hodí vedieť, či sa ešte zmestí ďalší text. --memory to po preklade napíše:
action26: memory [######################--------] 76 % full
used by the program: 35121 bytes
still free: 11215 bytes
biggest free piece: 5826 bytes (a new text or routine has to fit into one piece)
free under the ROM: 1380 bytes (biggest piece 1060)Voľná pamäť je rozdelená na kúsky. Nový text alebo rutina sa musí zmestiť do jedného, preto je dôležité hlavne číslo „biggest free piece“. Počíta sa po preklade, takže pamäť, ktorú program alokuje až za behu, v ňom nie je. Polia deklarované na pevnej adrese (ARRAY a(256)=$0700) sa započítajú samé. Buffery, ktoré program používa len za behu a nemá ich ako polia, povedz cez --reserve, napríklad --reserve $A100-$B7BF; inak by sa počítali ako voľné. Rozsah, v ktorom sa počíta, zúž cez --mem-lo a --mem-top.
Pamäť pod ROM ($C000–$CFFF a $D800–$FFF9) a v bankách program zvyčajne využíva na texty a tabuľky; jej voľné miesto je v prehľade na samostatnom riadku, lebo je to iný kus pamäte ako hlavná RAM.
Chceš vidieť, kde presne sú voľné kúsky, použi --memory-map. Každý kúsok je na vlastnom riadku, s adresou od–do:
action26: memory $0700-$BBFF
action26: program $0700-$09F3 756 bytes
action26: free $09F4-$0C57 612 bytes
action26: program $0C58-$0CE3 140 bytes
...
action26: free $9433-$9F5F 2861 bytesPri väčšom programe si podľa toho nájdeš diery, ktoré sa dajú vyplniť, a vidíš aj hranicu, od ktorej voľné miesto pokračuje až po koniec pamäte (tam sa dá umiestniť halda pre Alloc/Free).
Čo je v listingu
Listing ukazuje, na čo sa program preložil. Pre hello.act z kapitoly 2 začína takto:
; org $2000
2000 Main:
2000 A2 20 LDX #>__L2
2002 A9 0E LDA #<__L2
2004 4C 1C 20 JMP PrintE
2007 __start:
2007 A9 00 LDA #$00
2009 85 B7 STA $B7
200B 4C 00 20 JMP Main
200E __L2:
200E 0D 48 65 6C 6C 6F 2C 20 .BYTE ...
2016 41 74 61 72 69 21
; runtime: print
201C PrintE:Vľavo je adresa, za ňou bajty v pamäti a vpravo inštrukcia procesora. Vidno tri veci:
- procedúra
Mainmá tri inštrukcie: do registrov dá adresu textu a skočí doPrintE; - text
Hello, Atari!je uložený hneď za ňou (0Dje jeho dĺžka, 13); - za programom nasleduje runtime – rutiny knižnice. action26 pribalí len tie, ktoré program používa. Preto má celý
hello.xex277 bajtov.
Listing nemusíš vedieť čítať. Je užitočný, keď chceš vedieť, koľko miesta čo zaberá, alebo keď sa učíš assembler.
Spúšťanie
| Voľba | Čo robí |
|---|---|
--sim | spustí program vo vstavanom simulátore; klávesnica je klávesnica tvojho počítača |
--sim-stats | ako --sim, na konci vypíše počet vykonaných inštrukcií |
--sim-limit n | simulátor skončí najneskôr po n miliónoch inštrukcií (predvolene 10) |
--sim-mem druh | akú pamäť má simulovaný počítač: 64, 130xe a väčšie (kapitola 38) |
--run | spustí program v emulátore atari800 |
--emulator súbor | kde je atari800.exe, ak nie je v priečinku atari800 vedľa prekladača |
Čo simulátor vie a čo nie:
| Vie | Nevie |
|---|---|
| výpis textu a vstup z klávesnice | kresliť obrazovku, farby, grafické režimy |
súbory na D: (len v pamäti, počas behu) | zvuk |
| výpočty, polia, reťazce, ukazovatele | joystick a paddle |
rozšírenú pamäť (--sim-mem) | náhodné čísla (Rand vracia stále to isté) |
| časovač na adrese 20 |
Simulátor je rýchly spôsob, ako skúšať logiku programu. Na všetko, čo má byť vidieť a počuť, je emulátor.
--sim-stats sa hodí na porovnanie dvoch verzií programu – ktorá je rýchlejšia:
action26 for.act --sim-statsaction26: 6900 instruction(s) executedProgram, ktorý beží dlhšie ako desať miliónov inštrukcií, simulátor zastaví hlásením instruction limit reached. Ak to nie je nekonečná slučka, limit zväčši: --sim-limit 100.
Zdrojový text
| Voľba | Čo robí |
|---|---|
-I priečinok | kde hľadať súbory z INCLUDE (kapitola 23) |
-D meno=text | zavedie DEFINE meno="text" pred začiatkom programu |
--case-sensitive | rozlišuje veľké a malé písmená v menách |
--modern | zapne rozšírenia jazyka (kapitoly 35 až 39) |
--no-config | ignoruje nastavenia napísané v zdrojáku (kapitola 33) |
-D: meno z príkazového riadka
Súbor examples/stars-count.act používa meno COUNT, ktoré v programe nikto nedeklaroval:
; A name given on the command line: action26 stars-count.act -D COUNT=7
PROC Main()
BYTE i
FOR i=1 TO COUNT
DO
Put('*)
OD
PutE()
RETURNaction26 stars-count.act -D COUNT=7 --sim*******Bez -D prekladač ohlási error ACT008: undeclared name 'COUNT'. Hodí sa to, keď z jedného zdrojáka robíš viac verzií programu – skúšobnú a ostrú, anglickú a slovenskú.
Optimalizácia
| Voľba | Čo robí |
|---|---|
-O2 | najmenší a najrýchlejší kód – predvolené |
-O1 | menej úprav |
-O0 | kód v takom tvare, aký by dal pôvodný Action! |
Program sa správa vo všetkých troch prípadoch rovnako, líši sa veľkosť a rýchlosť. Pre for.act z kapitoly 13: 665 bajtov s -O0, 612 s -O1 a 589 s -O2.
-O0 má zmysel, keď porovnávaš výsledok s pôvodným prekladačom alebo keď program obsahuje strojový kód, ktorý sa spolieha na presný tvar okolitého kódu.
Nečitateľný súbor
| Voľba | Čo robí |
|---|---|
--scramble | zakóduje výsledný súbor, aby sa v ňom nedalo nič prečítať |
--scramble-fx meno | to isté, a kým sa program po nahratí dekóduje, na obrazovke beží efekt |
--scramble-level číslo | to isté, s úrovňou zakódovania: 1 (predvolená) alebo silnejšia 2 |
--scramble-key číslo | kľúč, od ktorého sa kóduje (napríklad $3A7F); s ním dá každý preklad rovnaký súbor |
Texty, ktoré program vypisuje, ležia v súbore XEX tak, ako si ich napísal. Kto súbor otvorí v editore, prečíta si ich – pri textovej hre aj riešenie. Súbor examples/secret.act:
; A file nobody can read: action26 secret.act --scramble
PROC Main()
PrintE("The password is SESAME.")
RETURNPrelož ho najprv obyčajne a nechaj Windows pohľadať v súbore slovo SESAME:
action26 secret.act
findstr /m SESAME secret.xexsecret.xexfindstr /m vypíše meno súboru, v ktorom slovo našiel. Teraz to isté s --scramble:
action26 secret.act --scramble
findstr /m SESAME secret.xexTentoraz nevypíše nič – slovo v súbore nie je. Program pritom robí presne to isté:
action26 secret.act --scramble --simThe password is SESAME.Čo prekladač urobil
Hotový program prekódoval bajt po bajte a pridal k nemu krátky dekodér. Ten sa po nahratí súboru spustí ako prvý, vráti pamäť do pôvodného stavu a až potom spustí tvoj program. V zdrojáku nemeníš nič a program o dekodéri nevie. Aj samotný dekodér je v súbore zakódovaný: pred ním leží krátky prvý stupeň (24 bajtov), ktorý ho pri prvom zavolaní rozkóduje na mieste. Zo súboru sa tak nedá prečítať ani kód dekodéra, ani jeho kľúč.
Čo to stojí, povie --verbose:
action26: scrambled 275 bytes (level 1, key $A7), decoder at $0600 (108 bytes), file 112 bytes longer- Súbor je dlhší asi o 110 bajtov – tu 399 namiesto 287.
- Pamäť programu sa nezmenšila. Dekodér leží mimo neho, na adrese
$0600(ak tam program sám niečo nahráva, tak hneď za programom), a po štarte ho program môže pokojne prepísať. - Štart trvá o chvíľu dlhšie. Hra s 26 kilobajtmi sa dekóduje asi pol sekundy.
Nie je to ochrana. Kto program spustí v emulátore, vidí v jeho pamäti všetko už dekódované. Zakódovanie bráni len tomu, aby si texty niekto prečítal priamo zo súboru.
Silnejšie zakódovanie: --scramble-level 2
Bežné --scramble kóduje každý bajt pomocou bajtu pred ním. Je to rýchle a dekodér je krátky, no kto ten postup pozná, napíše si program, ktorý súbor rozkóduje bez spúšťania. Voľba --scramble-level vyberá úroveň zakódovania:
| Úroveň | Ako kóduje | Dekodér | 26 KB trvá |
|---|---|---|---|
1 | každý bajt XOR bajt pred ním (predvolená, to isté ako --scramble) | 108 bajtov | 0,50 s |
2 | každý bajt XOR číslo z 16-bitového generátora pseudonáhodných čísel (LFSR) | +12 | asi 0,9 s |
action26 secret.act --scramble-level 2--scramble-level už znamená --scramble, oboje písať netreba. Efekty fungujú rovnako, napríklad --scramble-level 2 --scramble-fx bars.
Pri úrovni 2 čísla, ktorými sa bajty kódujú, vôbec nezávisia od programu a generátor beží bez prerušenia cez celý súbor – v súbore do 64 KB sa teda nikde neopakujú. Kto ich chce odstrániť, musí generátor napodobniť a poznať číslo, od ktorého začína – kľúč. Bez voľby --scramble-key si prekladač pri každom preklade vyberie nový náhodný kľúč, takže ten istý zdroják dá zakaždým iný súbor. Ak chceš, aby bol súbor pri každom preklade rovnaký (napríklad na porovnanie dvoch verzií), kľúč zadaj sám:
action26 secret.act --scramble-level 2 --scramble-key $3A7F --verboseaction26: scrambled 275 bytes (level 2, key $3A7F), decoder at $0600 (120 bytes), file 124 bytes longerKľúč je číslo od $0001 do $FFFF; nula nejde, generátor by z nej vyrábal len nuly. Pri úrovni 1 je kľúč jeden bajt od $01 do $FF, bez voľby platí $A7.
Kľúč ani tu nie je v súbore čitateľne, dekodér je zakódovaný rovnako ako pri úrovni 1. Čitateľný ostane len prvý stupeň a tabuľka, ktoré úseky pamäte sa majú dekódovať.
Ani úroveň 2 nie je ochrana: emulátor ukáže pamäť už dekódovanú a kto prvý stupeň pochopí, dostane sa ďalej. Len to dá podstatne viac práce.
Efekty: --scramble-fx
Pol sekundy, počas ktorej sa na obrazovke nič nedeje, vyzerá ako zaseknutý počítač. Staré programy na Atari preto pri rozbaľovaní kreslili pruhy. --scramble-fx meno zakóduje súbor rovnako ako --scramble a pridá do dekodéra efekt:
action26 secret.act --scramble-fx bars --runEfekt uvidíš len v emulátore (--run) alebo na skutočnom Atari – simulátor (--sim) obrazovku nekreslí. Pri takom malom programe iba preblikne; poriadne ho vidno pri programe s desiatkami kilobajtov.
| Meno | Čo je na obrazovke | Dekodér | 26 KB trvá |
|---|---|---|---|
none | nič – to isté ako --scramble | +0 bajtov | 0,50 s |
bars | farebné pásy cez celú obrazovku | +6 | 0,68 s |
bars-border | farebné pásy len na okrajoch | +3 | 0,58 s |
mono | čiernobiele pásy cez celú obrazovku | +8 | 0,72 s |
mono-border | čiernobiele pásy na okrajoch | +5 | 0,64 s |
rainbow | pravidelná dúha cez celú obrazovku | +6 | 0,68 s |
rainbow-border | dúha na okrajoch | +3 | 0,58 s |
slow | široké pomalé pásy cez celú obrazovku | +6 | 0,50 s |
slow-border | široké pomalé pásy na okrajoch | +3 | 0,50 s |
dots | bodky po celej obrazovke – znaky sa zmenia na zrnenie | +3 | 0,58 s |
dots-bars | bodky a farebné pásy naraz | +9 | 0,76 s |
blank | obrazovka zhasne, nič sa nekreslí | +20 | 0,36 s |
bars-blank | obrazovka zhasne, farebné pásy cez celú plochu | +23 | 0,42 s |
inc | obrazovka zhasne, biele čiarky na tmavočervenej ploche | +28 | 0,48 s |
inc-border | biele čiarky na tmavočervených okrajoch | +8 | 0,66 s |
Ako si vybrať:
- Čo najrýchlejší štart:
blank. Zhasnutá obrazovka neberie procesoru čas, preto je dekódovanie rýchlejšie než úplne bez efektu. - Efekt zadarmo:
slowaslow-border. Farbu menia len raz za 256 bajtov, takže nič nespomalia. - Nech obrazovka ostane čitateľná: varianty
-borderkreslia len do okrajov; text v strede ostane, ako bol. - Ako za starých čias:
barsaleboinc– ten kreslí to, čo rozbaľovač Super Packer.
Tri veci, ktoré je dobré vedieť:
- „Celá obrazovka“ platí pre bežnú textovú obrazovku, na ktorej sa program nahráva.
dotsje vidno len v textových režimoch. - Farby aj znaky sa po dekódovaní vrátia samy, program nemusí nič upratovať.
- Pri programe s dátami v skrytej pamäti (kapitola 38) beží dekodér po kúskoch počas celého nahrávania. Efekty so zhasnutou obrazovkou (
blank,bars-blank,inc) vtedy blikajú.
Voľbu si program môže niesť v sebe, riadkom ;@compile --scramble-fx bars na začiatku zdrojáka (kapitola 33). Rovnako ;@compile --scramble-level 2 --scramble-key $3A7F.
Časté chyby
| Hlásenie | Príčina |
|---|---|
error ACT200: invalid effect for --scramble-fx: stars (none, bars, …) | efekt s takým menom nie je; v zátvorke sú všetky, ktoré prekladač pozná |
error ACT200: missing effect after --scramble-fx (none, bars, …) | za --scramble-fx chýba meno efektu; bez efektu stačí --scramble |
warning ACT232: --scramble-fx inc on the command line overrides bars in the source | zdroják si pýta jeden efekt a príkazový riadok iný; platí príkazový riadok |
error ACT200: invalid level for --scramble-level: 3 (1, 2) | takú úroveň prekladač nepozná; sú len 1 a 2 |
error ACT200: invalid value for --scramble-key: $1FFFF (a number up to $FFFF, e.g. $3A7F) | kľúč je 16-bitové číslo, najviac $FFFF |
error ACT200: --scramble-key for --scramble-level 1 is a byte from $01 to $FF | úroveň 1 má kľúč len jeden bajt; dlhší kľúč patrí k úrovni 2 |
error ACT200: --scramble-key must not be 0 with --scramble-level 2 | generátor úrovne 2 nemôže začínať od nuly; zvoľ iný kľúč |
Zbalený súbor
| Voľba | Čo robí |
|---|---|
--pack-xex | zbalí výsledný súbor; Atari si ho počas nahrávania samo rozbalí |
Disketová mechanika Atari je pomalá. Kratší súbor sa preto nahrá rýchlejšie a na disketu sa ich zmestí viac. Starí programátori na to mali programy ako Super Packer; v Action26 stačí voľba. Program pm-lanes.act z kapitoly 42:
action26 pm-lanes.act --pack-xex --verboseaction26: packed 1 segments, loader at $0600 (180 bytes), buffer at $294D, file 2393 -> 1959 bytesSúbor sa skrátil z 2393 bajtov na 1959. Spúšťa sa rovnako ako predtým (--run, z DOS-u, z diskety s autorunom) a program o zbalení nevie.
Čo prekladač urobil
Každý kus programu zbalil (formátom ZX02, ktorý poznáš z PACK ZX02 v kapitole 39) a pridal krátky rozbaľovač so 180 bajtmi. DOS najprv nahrá rozbaľovač, potom zbalený kus a hneď ho zavolá; rozbaľovač kus rozbalí na jeho miesto. Až keď je všetko rozbalené, spustí sa tvoj program.
- Pamäť programu sa nezmenšila. Rozbaľovač leží na adrese
$0600(ak tam program sám niečo nahráva, tak za programom) a zbalené dáta za programom. Oboje treba len počas nahrávania, po štarte ich program môže pokojne prepísať. - Funguje s hocijakým DOS-om, aj s dátami v skrytej pamäti (kapitola 38) – aj tie sa zbalia.
- Malému programu nepomôže. Rozbaľovač má 180 bajtov, takže
secret.actz predchádzajúcej časti by narástol z 287 na 455 bajtov. Oplatí sa to až pri programoch s niekoľkými kilobajtmi, hlavne s textami a obrázkami, ktoré sa dobre balia.
Voľbu si program môže niesť v sebe riadkom ;@compile --pack-xex (kapitola 33).
Zbalený a zakódovaný
Zbalený súbor sa v editore číta horšie, no texty z neho nezmiznú. Kus, ktorý sa v programe neopakuje, si zbaľovač uloží tak, ako je:
action26 secret.act --pack-xex
findstr /m SESAME secret.xexsecret.xexAk sa texty nemajú dať prečítať, pridaj --scramble:
action26 secret.act --pack-xex --scramble
findstr /m SESAME secret.xexTeraz findstr nenájde nič. Prekladač najprv zbalí a potom zakóduje zbalené dáta; rozbaľovač ich pri nahrávaní najprv rozkóduje a potom rozbalí. Funguje to s oboma úrovňami aj s kľúčom (--scramble-level 2, --scramble-key), len efekty --scramble-fx so zbalením nejdú. Rozbaľovač narastie na 231 bajtov (s úrovňou 2 na 245).
Zakódujú sa všetky kusy programu, ktoré sa dajú zbaliť, aj keď sa zbalením neskrátia. Čitateľné ostanú len drobnosti: adresa štartu a nastavenia pod adresou $0400, napríklad farby.
Časté chyby
| Hlásenie | Príčina |
|---|---|
error ACT200: --pack-xex cannot show an effect: --scramble-fx bars only without --pack-xex (…) | zbalený súbor sa dá zakódovať, ale bez efektu; nechaj --scramble alebo --scramble-level |
error ACT200: --pack-xex: no segment gets shorter | program je taký malý, že by sa zbalením len predĺžil; prelož ho bez --pack-xex |
Upozornenia a chyby
| Voľba | Čo robí |
|---|---|
--strict | upozorní na všetko, čo by pôvodný Action! odmietol |
--quirks | napodobní aj známe chyby pôvodného prekladača |
--wextra | ďalšie upozornenia – napríklad volanie s menším počtom argumentov |
--werror | upozornenia sú chyby: program s varovaním sa nepreloží |
--max-errors n | po koľkých chybách prestať (predvolene 20) |
--verbose | vypíše, čo prekladač robí: veľkosť, adresy |
--strictpouži, keď má tvoj program bežať aj v pôvodnom Action! na skutočnom Atari.--quirkspouži, keď prekladáš starý program, ktorý sa spolieha na chyby originálu, a potrebuješ, aby sa správal presne ako kedysi. Vylučuje sa s--modern.--wextra --werrorje dobrá dvojica pre vlastné programy: prekladač je prísnejší a nedovolí varovania prehliadať.
Návratová hodnota
Pre toho, kto prekladač volá zo skriptu: 0 znamená úspech, 1 chyby v programe, 2 chybu v príkazovom riadku.
Zhrnutie
-omení meno výstupu,--listingukáže preložený kód.--simje na logiku,--runna všetko, čo má byť vidieť a počuť.-Ipridáva priečinky preINCLUDE,-Dzavádza mená.- Predvolená optimalizácia
-O2je najlepšia;-O0napodobňuje originál. --scrambleurobí súbor nečitateľným za cenu asi 110 bajtov a pol sekundy pri štarte;--scramble-fxk tomu pridá efekt na obrazovke a--scramble-level 2silnejšie kódovanie s náhodným alebo zadaným kľúčom.--pack-xexzbalí súbor, aby sa rýchlejšie nahral; oplatí sa pri programoch s niekoľkými kilobajtmi. S--scramblesa zbalené dáta aj zakódujú.--strictstráži zlučiteľnosť s pôvodným Action!,--modernzapína rozšírenia.--memorypo preklade povie, koľko pamäte ešte ostáva a aký veľký je najväčší voľný kus;--memory-mapukáže každý kúsok po adresách,--reservepovie, čo si program zaberá za behu.
Späť: 31. Bloky pamäte a chyby · Ďalej: 33. Nastavenia v zdrojáku