C64 Asembler (C64 Assembly) – Lekcija 4
Dobrodošli u lekciju 4 male škole programiranja u asembleru za Commodore 64. Danas ćemo preći neke izuzetno važne asemblerske naredbe, a kao i obično, daćemo primere i BASIC ekvivalente.
Napomene, saveti i objašnjenja
Prilikom unosa koda u Turbo Assembleru i kompajliranja programa, kada se nađete u BASIC-u i želite da radite u njemu, preporučujemo da otkucate naredbu SYS 64738. Ovo će restartovati računar, dok će Turbo Assembler i program koji ste uneli ostati netaknuti. Razlog je taj što se prilikom startovanja Turbo Assemblera poremete neka osnovna podešavanja sistema, pa neke BASIC naredbe neće raditi ispravno (npr. PEEK) ili će se pokazati da nema dovoljno memorije ako želite da unesete BASIC program.
Da biste iz BASIC-a pokrenuli vaš mašinski program, kucajte SYS praćeno adresom početka programa u decimalnom formatu (npr. SYS 4096). Da biste se vratili u Turbo Assembler i vaš izvorni program, kucajte SYS 333 ili SYS 36864.
Vrste indeksiranja
Kao što smo već rekli u prethodnim lekcijama, ne postoje šesnaestobitni registri koji bi obuhvatili celokupnu memoriju računara i koji bi se mogli automatski povećavati ili smanjivati. To je bitno za manipulaciju svim memorijskim blokovima (0-65535 / $0-$FFFF). Zbog toga postoje preindeksirano i postindeksirano indeksiranje.
Sa ovim imamo ukupno pet vrsta indeksiranja (neposredno, nulta strana, apsolutno, preindeksirano i postindeksirano). Pokazaćemo ih pomoću naredbe LD (učitavanje vrednosti u akumulator/registar). Naravno, i druge naredbe, poput ST (smeštanje vrednosti iz registra u memorijske lokacije), mogu koristiti ova indeksiranja:
- LDA #a – neposredno – direktno se unosi osmobitni broj argumenta a u akumulator.
- LDA n – nulta strana – osmobitni broj argumenta n iz memorije $0-$FF unosi se u akumulator.
- LDA n,X – nulta strana uvećana za X – vrednost iz memorije uvećane za registar X unosi se u akumulator.
- LDA ap – apsolutno – osmobitni broj argumenta ap iz memorije $0-$FFFF unosi se u akumulator.
- LDA ap,X – apsolutno – vrednost iz memorije uvećane za registar X unosi se u akumulator.
- LDA ap,Y – apsolutno – vrednost iz memorije uvećane za registar Y unosi se u akumulator.
- LDA (pr,X) – preindeksirano – koristi niži i viši bajt adrese u nultoj strani uvećane za registar X.
- LDA (po),Y – postindeksirano – koristi adresu iz nulte strane uvećanu za registar Y.
Ova indeksiranja smo radili u prethodnim lekcijama, osim preindeksiranog i postindeksiranog, koje ćemo upoznati u današnjoj lekciji.
Matematičke operacije (sabiranje i oduzimanje)
Sabiranje (ADC)
ADC #broj/adresa – sabiranje sadržaja akumulatora sa osmobitnim brojem ili vrednosti memorijske lokacije i vrednosti C-bita (prenos prekoračenja) registra stanja procesora.
Pre sabiranja treba dati naredbu CLC koja resetuje C-bit registra stanja procesora na nulu.
Evo kako sabiranje funkcioniše:
*= $1000
LDA #$00
STA $04
LDA #$05
STA $02
LDA #$F9
STA $03
LDA $02
CLC
ADC $03
STA $04
RTS
Kompajliranjem i pokretanjem ovog programa, a zatim proverom sa PRINT PEEK(4), videćete vrednost 254 (5 + 249).
Primer sa prekoračenjem:
*= $1000
LDA #$00
STA $04
STA $05
LDA #$14
STA $02
LDA #$FA
STA $03
LDA $02
CLC
ADC $03
STA $04
LDA #$00
ADC #$00
STA $05
RTS
Nakon pokretanja, PRINT PEEK(4) + PEEK(5) * 256 će prikazati 14 + 1 * 256 = 270. BASIC ekvivalent je jednostavan: PRINT 20 + 250.
Oduzimanje (SBC)
SBC #broj/adresa – oduzimanje od sadržaja akumulatora datog osmobitnog broja ili sadržaja memorijske lokacije i vrednosti C-bita registra stanja procesora.
Pre oduzimanja treba dati naredbu SEC koja setuje C-bit registra stanja procesora na jedinicu.
Evo kako oduzimanje funkcioniše:
*= $1000
LDA #$00
STA $04
LDA #$F9
STA $02
LDA #$05
STA $03
LDA $02
SEC
SBC $03
STA $04
RTS
Nakon pokretanja, PRINT PEEK(4) će prikazati 244 (249 – 5).
Primer oduzimanja šesnaestobitnih brojeva:
*= $1000
LDA #$16
STA $02
LDA #$0A
STA $03
LDA #$11
STA $04
LDA #$B0
STA $05
SEC
LDA $04
SBC $02
STA $04
LDA $05
SBC $03
STA $05
RTS
Naredbom PRINT PEEK(4) + PEEK(5) * 256 dobićemo 251 + 165 * 256 = 42491. Ovo odgovara oduzimanju $B011 (45073) – $0A16 (2582).
Kao što ste videli, programiranje u asembleru je zahtevnije od BASIC-a, ali se isplati zbog neprikosnovene brzine izvršavanja i drastično manjeg zauzeća memorije.
Naredbe za poređenje
Naredbe za poređenje su veoma važne za stvaranje petlji i uslovnih skokova. Ove naredbe direktno utiču na N, Z i C bitove registra procesora.
- CMP #broj/adresa – poređenje sadržaja akumulatora A sa brojem ili vrednosti memorijske lokacije.
- A = broj/sadržaj adrese → Z-bit je setovan
- A > broj/sadržaj adrese → C-bit je setovan
- A < broj/sadržaj adrese → N-bit je setovan
- CPX #broj/adresa – poređenje sadržaja registra X.
- CPY #broj/adresa – poređenje sadržaja registra Y.
Naredbe za uslovne skokove
Naredbe za uslovne skokove u potpunosti zavise od stanja bitova u registru procesora:
- BNE adresa – skok ako je Z=0.
- BEQ adresa – skok ako je Z=1.
- BCC adresa – skok ako je C=0.
- BCS adresa – skok ako je C=1.
- BPL adresa – skok ako je N=0.
- BMI adresa – skok ako je N=1.
- BVC adresa – skok ako je V=0.
- BVS adresa – skok ako je V=1.
Ekvivalenti BASIC naredbi:
- IF A=0 THEN GOTO → BEQ
- IF A<>0 THEN GOTO → BNE
- IF A<M THEN GOTO → BMI
- IF A>=M THEN GOTO → BPL
- IF X=0 THEN GOTO → CPX, BEQ
- IF X<>0 THEN GOTO → CPX, BNE
- IF Y=0 THEN GOTO → CPY, BEQ
- IF Y<>0 THEN GOTO → CPY, BNE
Primeri punjenja ekrana
Primer 1: Ispunjenje ekrana pomoću preindeksiranog indeksiranja
*= $1000
LDA #$00
STA $02
LDA #$04
STA $03
LDX #$00
LDA #$01
OPET:
STA ($02,X)
INC $02
BNE OPET
INC $03
LDY $03
CPY #$08
BNE OPET
RTS
Primer 2: Ispunjenje ekrana pomoću postindeksiranog indeksiranja
*= $1000
LDA #$00
STA $02
LDA #$04
STA $03
LDY #$00
LDA #$01
OPET:
STA ($02),Y
INY
BNE OPET
INC $03
LDX $03
CPX #$08
BNE OPET
RTS
BASIC ekvivalent (primera 1 i 2):
10 FOR I=1024 TO 2023
20 POKE I,1
30 NEXT I
Ovom BASIC programu treba najmanje 5 sekundi da ispuni ekran, što jasno pokazuje ubedljivu nadmoć mašinskog programa.
Poređenje dužina programa:
- Mašinac (primer 2): $1000-$1019 → 25 bajta
- BASIC: $0803-$082c → 41 bajt
Primer 3: Ispunjenje ekrana pomoću blokova ekranske memorije
Ovaj program popunjava blokove memorije direktno, ali je manje fleksibilan.
*= $1000
LDX #$00
LDA #$01
OPET1:
STA $0400,X
INX
BNE OPET1
OPET2:
STA $0500,X
INX
BNE OPET2
OPET3:
STA $0600,X
INX
BNE OPET3
OPET4:
STA $0700,X
INX
BNE OPET4
RTS
Ovaj pristup je koristan za manji broj blokova, ali je za manipulaciju celokupnom memorijom bolje koristiti preindeksirano i postindeksirano indeksiranje.
Kao što vidite, asemblerski kompajler je daleko nadmoćniji od BASIC interpretera u brzini i efikasnosti.

