25. Strojový kód: blok [ … ] a rutina na adrese
Na čo to je
Procesor Atari (6502) rozumie len číslam – strojovému kódu. Prekladač mení tvoj program práve na také čísla. Action! dovoľuje vložiť strojový kód do programu aj priamo, a zavolať rutinu, ktorá už niekde v pamäti je (napríklad v operačnom systéme).
Túto kapitolu nemusíš vedieť použiť. Stačí vedieť, čo ten zápis znamená, keď ho stretneš v cudzom programe. Staré programy z časopisov ho používajú často – na miestach, kde záležalo na rýchlosti.
Ako sa to píše
Blok kódu
[$EE $00 $06]Čísla v hranatých zátvorkách prekladač vloží do programu presne tak, ako sú, bajt za bajtom. Nič nekontroluje. Číslo väčšie ako 255 sa vloží ako dva bajty (nižší prvý). V bloku môže stáť aj meno premennej alebo rutiny – vloží sa jej adresa.
Blok môže stáť medzi príkazmi rutiny alebo tvoriť celé jej telo.
Rutina zo strojového kódu
PROC Bump=*()
[$EE $00 $06 $60]=* znamená „táto rutina začína práve tu a jej telo si napíšem sám“. Prekladač k nej nepridá nič – ani uloženie parametrov. Kód musí sám skončiť inštrukciou návratu ($60).
Rutina na pevnej adrese
PROC CIO=$E456(BYTE a, x)Hovorí: „na adrese $E456 už rutina je, len jej dávam meno“. Žiadne telo nenasleduje. Takto sa volajú rutiny operačného systému. Argumenty sa odovzdajú v registroch procesora: prvý bajt v registri A, druhý v X, tretí v Y.
Celý program
Súbor examples/machine.act:
; Machine code inside an Action! program
BYTE counter=1536 ; a byte at address $0600
PROC Bump=*() ; a routine written in machine code
[$EE $00 $06 ; INC $0600 - add 1 to the byte at $0600
$60] ; RTS - return
PROC Main()
counter=5
Bump()
Bump()
Print("After two calls: ")
PrintBE(counter)
[$CE $00 $06] ; DEC $0600 - a code block between statements
Print("After the code block: ")
PrintBE(counter)
RETURNPreklad a spustenie
action26 machine.act --simČo uvidíš
After two calls: 7
After the code block: 6Ako to funguje
$EE $00 $06je inštrukcia procesoraINC $0600: pripočítaj 1 k bajtu na adrese$0600. Prvý bajt je kód inštrukcie, ďalšie dva adresa (nižší bajt prvý – ako v kapitole 24).$60jeRTS, návrat z rutiny.counterje premenná položená na adresu$0600(1536), takže strojový kód a program v Action! menia ten istý bajt.Bump()sa volá ako každá iná procedúra.[$CE $00 $06]uprostredMainjeDEC $0600– odčítaj 1. Vykoná sa v poradí medzi okolitými príkazmi.
Komentáre za bajtmi hovoria, aká inštrukcia to je. Bez nich je blok kódu len rad čísel, ktorým nikto nerozumie – ani autor o mesiac neskôr.
Kedy to použiť
Skoro nikdy. action26 prekladá Action! do rýchleho kódu a to, čo sa kedysi písalo v strojovom kóde, dnes zvyčajne netreba. Výnimky:
- obsluha prerušení (napríklad zmena farby na každom riadku obrazovky),
- volanie rutiny operačného systému, ktorú knižnica nemá,
- prepis starého programu, ktorý bloky kódu už obsahuje.
Ak sa chceš strojovému kódu venovať, action26 má pohodlnejší spôsob než čísla: blok ASM … ENDASM, do ktorého sa píšu inštrukcie menami (inc counter). Je to rozšírenie nad rámec pôvodného Action! a opisuje ho kapitola 37.
Časté chyby
| Čo sa stalo | Čo sa stane |
|---|---|
chýba $60 na konci rutiny =* | procesor pokračuje do toho, čo v pamäti nasleduje |
| preklep v jednom čísle | iná inštrukcia; program zvyčajne spadne |
| blok kódu zmení register, s ktorým okolitý program počíta | chyba na inom mieste, ťažko hľadateľná |
| meno rutiny na adrese s nesprávnou adresou | skok do neznáma |
Prekladač v bloku kódu nekontroluje nič.
Vyskúšaj si
- Pridaj tretie volanie
Bump()a over výsledok. - Zmeň prvý bajt bloku v
Mainz$CEna$EE. Čo sa vypíše? - Prelož program s voľbou
--listing machine.lsta otvor vzniknutý súbor v editore. Nájdi v ňom svoje bajty – a pozri, ako prekladač preložil ostatné riadky.
action26 machine.act --listing machine.lstZhrnutie
[ … ]vloží do programu bajty presne tak, ako sú napísané.PROC Meno=*()je rutina, ktorej telo je celé zo strojového kódu.PROC Meno=adresa(…)dá meno rutine, ktorá už v pamäti je.- Prekladač strojový kód nekontroluje; komentuj každú inštrukciu.
Späť: 24. Pamäť počítača · Ďalej: 26. Formátovaný výpis a prevody