Assembler 8 - Nepodmíněné skoky, zásobník, zbytek ...
Nepodmíněné skoky JMP a JSR
Dnes se zaměříme na příkazy, které jsme již tak nějak vlastně probrali a dá se říct, že bez vysvětlování pochopili ...
Jedná se o nepodmíněné skoky. Jsou to skoky, které nejsou ovlivňovány žádnými vlastnostmi statusregistru.
JMP $adresa - Program skočí na adresu, kde pokračuje ve zpracování kódu
JSR $adresa - Program skočí na adresu, kde pokračuje ve zpracování kódu do chvíle, než narazí na příkaz RTS.
Jakmile přijde instrukce RTS, vrací se program zpět na místo, kde jsme jsr vyvolali. Příklad:
|
lda #2 |
|
|
sta $d020 |
|
|
jsr znak |
|
|
lda #1 |
|
|
sta $d021 |
|
|
rts |
;konec programu |
znak |
lda #01 |
|
|
sta $0400 |
|
|
rts |
;konec podprogramu znak |
|
|
|
Zde je jasně vidět, že instrukce JSR je skok na podprogram. Něco jako GOSUB v basicu.
Zásobník - Stackpointer - SP
Máte-li ve svém prográmku obsazeny všechny registry a přeukládání registrů na adresy (byď už v nulté stránce) je pro Vás pomalé. ... co teď?
Zde můžeme využít zásobník. Zásobník je prostor hodnot, který má velikost 255 hodnot. Nachází se v paměti od $0100 -$01FF . Systém vkládání do zásobníku je takový, že data nasypaná do zásobníku od 1 do 10 můžeme zpět vybrat jen naopak od 10 do 1. Systém zásobníku se anglicky jmenuje LIFO .. tzn. Last In, First Out.
Do zásobníku můžeme vložit obsah akumulátoru nebo aktuální stav statusrgistru, je-li to potřeba.
PHA - uloží akumulátor do zásobníku
PLA - vybere ze zásobníku hodnotu a vloží do akumulátoru
PHP - uloží statusregistr do zásobníku
PLP - vybere ze zásobníku hodnotu a nastaví s ní statusregistr
Je potřeba si uvědomit, že do zásobníku se ukládají v průběhu běhu programu i vektory skoků JSR, JMP a další hodnoty potřebné pro běh instrukcí.
Všechny tyto doujbytové instrukce se ukládají do zásobníku ve formě nejdříve LO a HI byte.
Abychom pochopili, jak se ukládají adresy do zásobníku a hlavně,že i např.instrukce JSR si uchovává svoji adresu pro skok zpět do zásobníku, ukážeme si malý příklad.
|
lda #2 |
|
|
sta $d020 |
; nastavime barvy obrazovky a ramu |
|
sta $d021 |
|
|
jsr vybrat |
; odskocime si na vybrat |
|
lda #1 |
; sem se jiz nedostaneme !! |
|
sta $0400 |
|
|
rts |
|
vybrat |
pla |
; zde vybereme dve hodnoty ze zasobniku |
|
pla |
; ktere si zd nechalo JSR |
|
rts |
; ukoncime podprogram |
Musíme si proto dávat zatracený pozor, abychom ze zásobníku nevybrali hodnot více než jsme vložili, protože v té chvíli dojde ke krachu systému.
Nastavování a mazání příznaků statusregistru
O statusregistu jsme se již dozvěděli maximum v pátém díle assembleru .
Zde si pouze ukážeme možné instrukce pro změnu stavu statusregistru. Některé jsme již probírali, některé jsou pro nás takřka zbytečné a některé probereme v dalších dílech věnovaných přerušení.
SEC - nastav CARRY na 1
CLC - nastav CARRY na 0
SED - nastav DECIMAL na 1
CLD - nastav DECIMAL na 0
SEI - nastav INTERRUPT na 1
CLI - nastav INTERRUPT na 0
CLV - nastav OVERFLOW na 0
BIT a BRK (čuk a gek) , RTI , NOP
Nebojte-se .. kvalitní ruskou literaturu vynecháme. BIT a BRK nejsou bratři z románu Arkadije Petroviče Gajdara, ale zbylé instrukce, které jsme ještě nezvládli ..
BRK - narazí-li běh programu na tuto instrukci, následuje skok na ukazatele BREAK přerušení. Není-li break přerušení nastaveno, program tuhne.
RTI - nývrat z přerušení (probereme později důkladně)
BIT - Test bitů paměti s bity střadače. (7-mý bit jde do příznaku Negative, 6-tý do příznaku Overflow) ...
NOP - Nic nedělá, jen prvá dva takty
Zde bych rád prohlásil, že jsme teoreticky probrali všechny officiální instrukce počítače Commodore 64. Je jich celkem 51 a se všemi možnými syntaxy jich je 151. Existují samozřejmě i instrukce neofficiální, ale podpora v assemblerech takřka chybí. Ale nebojte, o nic nepřicházíte. Neofficiální instrukce jsou odpad stavby procesoru, tudíž i funkce těchto instrukcí je velmi prapodivný ..
V dalších dílech budeme objevovat nejen důležité adresy , ale seznámíme se (doufám dokonale) s celým systémem a hardwarem počítače Commodore 64. A nyní tabulka všech instrukcí assembleru.
Přehled instrukcí assembleru
In. |
P |
#$nn
OP/N/# |
$HHLL
OP/N/# |
$LL
OP/N/# |
A
OP/N/# |
Impl.
OP/N/# |
($LL,x)
OP/N/# |
($LL),y
OP/N/# |
$LL,x
OP/N/# |
$HHLL,x
OP/N/# |
$HHLL,y
OP/N/# |
Relat.
OP/N/# |
($HHLL)
OP/N/# |
$LL,y
OP/N/# |
|
ADC |
a |
69/2/2 |
6D/4/3 |
65/3/2 |
|
|
61/6/2 |
71/5/2 |
75/4/2 |
79/4/3 |
|
|
|
|
***--* |
AND |
a |
29/2/2 |
2D/4/3 |
25/3/2 |
|
|
21/6/2 |
31/5/2 |
35/4/2 |
39/4/3 |
|
|
|
|
**---- |
ASL |
|
|
0E/6/3 |
06/5/2 |
0A/2/1 |
|
|
|
16/6/2 |
|
|
|
|
|
***--- |
BCC |
b |
|
|
|
|
|
|
|
|
|
|
90/2/2 |
|
|
------ |
BCS |
b |
|
|
|
|
|
|
|
|
|
|
B0/2/2 |
|
|
------ |
BEQ |
b |
|
|
|
|
|
|
|
|
|
|
F0/2/2 |
|
|
------ |
BIT |
|
|
2C/4/3 |
24/3/2 |
|
|
|
|
|
|
|
|
|
|
b7*--b6 |
BMI |
b |
|
|
|
|
|
|
|
|
|
|
30/2/2 |
|
|
------ |
BNE |
b |
|
|
|
|
|
|
|
|
|
|
D0/2/2 |
|
|
------ |
BPL |
b |
|
|
|
|
|
|
|
|
|
|
10/2/2 |
|
|
------ |
BRK |
|
|
|
|
|
00/7/1 |
|
|
|
|
|
|
|
|
---*-- |
BVC |
b |
|
|
|
|
|
|
|
|
|
|
50/2/2 |
|
|
------ |
BVS |
b |
|
|
|
|
|
|
|
|
|
|
70/2/2 |
|
|
------ |
CLC |
|
|
|
|
|
18/2/1 |
|
|
|
|
|
|
|
|
--*--- |
CLD |
|
|
|
|
|
D8/2/1 |
|
|
|
|
|
|
|
|
----*- |
CLI |
|
|
|
|
|
58/2/1 |
|
|
|
|
|
|
|
|
---*-- |
CLV |
|
|
|
|
|
B8/2/1 |
|
|
|
|
|
|
|
|
----*- |
CMP |
a |
C9/2/2 |
CD/4/3 |
C5/3/2 |
|
|
C1/6/2 |
D1/5/2 |
D5/4/2 |
DD/4/3 |
D9/4/3 |
|
|
|
***--- |
CPX |
|
E0/2/2 |
EC/4/3 |
E4/3/2 |
|
|
|
|
|
|
|
|
|
|
***--- |
CPY |
|
C0/2/2 |
CC/4/3 |
C4/3/2 |
|
|
|
|
|
|
|
|
|
|
***--- |
DEC |
|
|
CE/6/3 |
C6/5/2 |
|
|
|
|
D6/6/2 |
DE/7/3 |
|
|
|
|
**---- |
DEX |
|
|
|
|
|
CA/2/1 |
|
|
|
|
|
|
|
|
**---- |
DEY |
|
|
|
|
|
88/2/1 |
|
|
|
|
|
|
|
|
**---- |
EOR |
a |
49/2/2 |
4D/4/3 |
45/3/2 |
|
|
41/6/2 |
51/5/2 |
55/4/2 |
5D/4/3 |
59/4/3 |
|
|
|
**---- |
INC |
|
|
EE/6/3 |
E6/5/2 |
|
|
|
|
F6/6/2 |
FE/7/3 |
|
|
|
|
**---- |
INX |
|
|
|
|
|
E8/2/1 |
|
|
|
|
|
|
|
|
**---- |
INY |
|
|
|
|
|
C8/2/1 |
|
|
|
|
|
|
|
|
**---- |
JMP |
|
|
4C/3/3 |
|
|
|
|
|
|
|
|
|
|
|
------ |
JSR |
|
|
20/6/3 |
|
|
|
|
|
|
|
|
|
|
|
------ |
LDA |
a |
A9/2/2 |
AD/4/3 |
A5/3/2 |
|
|
A1/6/2 |
B1/5/2 |
B5/4/2 |
BD/4/3 |
B9/4/3 |
|
|
|
**---- |
LDX |
a |
A2/2/2 |
AE/4/3 |
A6/3/2 |
|
|
|
|
|
|
BE/4/3 |
|
|
B6/4/2 |
**---- |
LDY |
a |
A0/2/2 |
AC/4/3 |
A4/3/2 |
|
|
|
|
B4/4/2 |
BC/4/3 |
|
|
|
|
**---- |
LSR |
|
|
4E/6/3 |
46/5/2 |
4A/2/1 |
|
|
|
56/6/2 |
5E/7/3 |
|
|
|
|
-**--- |
NOP |
|
|
|
|
|
EA/2/1 |
|
|
|
|
|
|
|
|
------ |
ORA |
|
09/2/2 |
0D/4/3 |
05/3/2 |
|
|
01/6/2 |
11/5/5 |
15/4/2 |
1D/4/3 |
19/4/3 |
|
|
|
**---- |
PHA |
|
|
|
|
|
48/3/1 |
|
|
|
|
|
|
|
|
------ |
PHP |
|
|
|
|
|
08/3/1 |
|
|
|
|
|
|
|
|
------ |
PLA |
|
|
|
|
|
68/4/1 |
|
|
|
|
|
|
|
|
**---- |
PLP |
|
|
|
|
|
28/4/1 |
|
|
|
|
|
|
|
|
restored |
ROL |
|
|
2E/6/3 |
26/5/2 |
2A/2/1 |
|
|
|
36/6/2 |
3E/7/3 |
|
|
|
|
***--- |
ROR |
|
|
6E/6/3 |
66/5/2 |
6A/2/1 |
|
|
|
76/6/2 |
7E/7/3 |
|
|
|
|
***--- |
RTI |
|
|
|
|
|
40/6/1 |
|
|
|
|
|
|
|
|
restored |
RTS |
|
|
|
|
|
60/6/1 |
|
|
|
|
|
|
|
|
------ |
SBC |
a |
E9/2/2 |
ED/4/3 |
E5/3/2 |
|
|
E1/6/2 |
F1/5/2 |
F5/4/2 |
FD/4/3 |
F9/4/3 |
|
|
|
***--* |
SEC |
|
|
|
|
|
38/2/1 |
|
|
|
|
|
|
|
|
--*--- |
SED |
|
|
|
|
|
F8/2/1 |
|
|
|
|
|
|
|
|
----*- |
SEI |
|
|
|
|
|
78/2/1 |
|
|
|
|
|
|
|
|
---*-- |
STA |
|
|
8D/4/3 |
85/3/2 |
|
|
81/6/2 |
91/6/2 |
95/4/2 |
9D/5/3 |
99/5/3 |
|
|
|
------ |
STX |
|
|
8E/4/3 |
86/3/2 |
|
|
|
|
|
|
|
|
|
96/4/2 |
------ |
STY |
|
|
8C/4/3 |
84/3/2 |
|
|
|
|
94/4/2 |
|
|
|
|
|
------ |
TAX |
|
|
|
|
|
AA/2/1 |
|
|
|
|
|
|
|
|
**---- |
TAY |
|
|
|
|
|
A8/2/1 |
|
|
|
|
|
|
|
|
**---- |
TSX |
|
|
|
|
|
BA/2/1 |
|
|
|
|
|
|
|
|
**---- |
TXA |
|
|
|
|
|
8A/2/1 |
|
|
|
|
|
|
|
|
**---- |
TXS |
|
|
|
|
|
9A/2/1 |
|
|
|
|
|
|
|
|
------ |
TYA |
|
|
|
|
|
98/2/1 |
|
|
|
|
|
|
|
|
**---- |
OP - Kód instrukce
N - počet cyklů
# - počet bytů
a - přičti 1 k "N" přecházíš-li na další stránku
b - přičti 1 k "N" jde-li větvení na tutéž stránku, přičti 2 k "N" jde-li větvení na jinou stránku