Recenze - Navigátor

12 Assembler
41 Encyklopedie
30 Hardware
15 Hra
12 Párty
7 Programování
12 Sofware

HRA

Fantasy Boulder Dash I
Herní styl Boulder Dash
Multiplayer Bez multiplayeru
Rok vydání 2001
Programátor Peter Liepa & H.M. Murdo...
Grafik (Unknown)

INTRO

Assembler 7 - Logické operace , násobení, dělení, rotace

Dnes si naučíme pracovat s logickými operacemi AND, ORA, EOR a násobit, dělit hodnoty včetně rolování bitů.
Tyto všechny instrukce pracují pouze s akumulátorem.... a kdo si libuje v jedničkách a nulách, dnes si určitě užije.


Logické operace - AND

Pro vysvětlení logických operací zabrousíme do binárního zápisu, kterým Turboassembler na C64 nebo pro PC disponuje.
Instrukce AND provádí binární logický součin. Vysvětlení je následující: příklad je binární vyjádření následujícího příkladu :

LDA #$8E
AND #$1D
STA $2000

128
64
32
16
8
4
2
1
#
#$
1
0
0
0
1
1
1
0
#142
#$8E
0
0
0
1
1
1
0
1
#29
#$1D
0
0
0
0
1
1
0
0
#12
#$0C

Logický AND provede s bity následující :

1 a 1 = 1
1 a 0 = 0
0 a 1 = 0
0 a 0 = 0

Počítáme-li v našich programech s potřebou logických operací, je výhodné a perfektně přehledné používat binární zápis hodnot. Výše uvedený příklad tudíž lze zapsat jednoduše pomocí binárních hodnot takto :

LDA #%10001110
AND #%00011101
STA $2000

Výsledek operace naleznete na adrese $2000. Příkaz and můžeme používat ve všech těchto podobách syntaxu.

AND #$xx
AND $xxxx
AND $xx
AND $xx,x
AND $xxxx,x
AND $xxxx,y
AND ($xx,x)
AND ($xx),y


Logické operace - ORA

Instrukce ORA je logický součet bitů. Opět si vyzkoušíme instrukci na stejném příkladě jako u instrukce AND.

LDA #$8E
ORA #$1D
STA $2000

128
64
32
16
8
4
2
1
#
#$
1
0
0
0
1
1
1
0
#142
#$8E
0
0
0
1
1
1
0
1
#29
#$1D
1
0
0
1
1
1
1
1
#159
#$9F

Logický ORA provede s bity následující :

1 a 1 = 1
1 a 0 = 1
0 a 1 = 1
0 a 0 = 0

Opět zde platí, že v případech, kde používáme logické operace je lepší použít binární zápis dat.

Syntaxy pro ORA jsou totožná jako pro AND, tudíž lze orovat jak hodnoty, tak hodnoty na adresach.


Logické operace - EOR

Instrukce EOR neboli Exclusive OR je poslední z logických instrukcí. Opět stejný příklad.

LDA #$8E
EOR #$1D
STA $2000

128
64
32
16
8
4
2
1
#
#$
1
0
0
0
1
1
1
0
#142
#$8E
0
0
0
1
1
1
0
1
#29
#$1D
1
0
0
1
0
0
1
1
#147
#$93

Logický EOR provede s bity následující :

1 a 1 = 0
1 a 0 = 1
0 a 1 = 1
0 a 0 = 0

A tak jako u AND, ci ORA i instrukce EOR má stejné možnosti zápisu a také ovlivňuje pouze akumulátor.

Všechny tyto příkazy si vysvětlíme v příkladě na konci lekce .. a že to už bude opravdu pořádný příklad ... uvidíte :)


Násobení - ASL

Násobení je opět instrukce pracující pouze s akumulátorem. Instrukce ASL dokáže naši hodnotu vynásobit dvěma, kde osmý, tj. nejvyšší bit nastavuje příznak CARRY. V praxi to vypadá následovně.

#$04 * 2 = #$08

LDA #$04
ASL
STA $2000

#$08 * 2 = #$10

LDA #$08
ASL
STA $3000

zkuste si ověřit, jaké hodnoty se nachází na aresách 2000 a 3000. Ale když už jsme načali tento díl bitovými operacemi, podívejme se na instrukci násobení ASL taktéž bitově.

#$04 * 2 = #$08

LDA #%00110100
ASL
STA $2000
na adreses $2000 najdeme hodnotu $%01101000

128
64
32
16
8
4
2
1
#
#$
0*
0
1
1
0
1
0
0
#52
#$34
0
1
1
0
1
0
0
0
#104
#$68

Zde jsme vynásobili hodnotu 52 . Všimněte si , že násobení je posun bitů do leva o 1 pozici ! Bit označený hvězdičkou se sice nenásobí, ale zde nastavuje příznak CARRY na 0. Další příklad vynásobí hodnotu dvěma a nastaví CARRY na 1.

128
64
32
16
8
4
2
1
#
#$
1*
0
1
1
0
0
0
0
#176
#$B0
0
1
1
0
0
0
0
0
#96
#$60

Zde jsme došli k výsledku následovně: 176 * 2 - 256 = 96 , kde poslední bit nastavuje CARRY na 1 a tudíž je-li C nastaveno, víme, že násobení přeteklo přes osmý bit a je zapotřebí s tímto počítat.

Procesor 6502 nám ovšem dovoluje násobit pouze hodnotou 2. Jak ale vynásobíme naši hodnotu například devíti ???

LDA #$04 A = 4
ASL A * 2
ASL A * 2 - ( jako A * 4)
ASL A * 2 - ( jako A * 8)
CLC  
ADC #$04 A = A + #$04
STA $2000 výsledek ulož na adresu

Na tomto příkladě je jasně vidět, že násobit např. 9x .. lze ..

Syntaxy :

ASL
ASL $xxxx
ASL $xx
ASL $xx,x
ASL $xxxx,x


Dělení - LSR

A Dělení není nic jiného jako násobení s tím rozdílem, že se bity při násobení posouvají směrem doprava a první bit ( zde první zprava) nastavuje CARRY. Příklad:

128
64
32
16
8
4
2
1
#
#$
0
0
1
1
0
1
0
0*
#52
#$34
0
0
0
1
1
0
1
0
#26
#$1A

V tomto případě je po dělení Carry nastaveno na 0.
Jak ale vydělit hodnotu 150 již zmiňovanými devíti ?? Při násobení je to logické, že nevznikají desetinná místa, ale u dělení je to jinak. Při dělení 150/9 vznikne výsledek 16.66666667 takže co v assembleru s tím ? V assembleru při počítání s výsledkem dělení může vziknout určitá nepřesnost.
To znamená, že vydělíme-li hodnotu 150 osmi a poté výsledek vynásobíme osmi, konečný výsledek se bude lišit.

LDA #150 hodnotu 150
LSR vydělíme dvěma
LSR čtyřma
LSR osmi
STA $2000 výsledek uložíme na adresu 2000
   
LDA $2000 nacteme hodnotu z adresy 2000
ASL vynásobíme dvěma
ASL čtyřma
ASL osmi
STA $2001 výsledek uložíme na adresu 2001

A k čemu jsme se dopočítali ?? Na adrese $2001 se po dělení osmi a následném vynásobení osmi nachází hodnota jiná než 150 a to 144 ... holt .. počítání bez desetinně čárky jde pěkně na nervy ...

Syntaxy jsou stejné pro LSR jak pro instrukci ASL


ROL - Rotate on left neboli rolujeme s bity do leva

Jak již název napovídá, instrukce ROL provádí rotaci bitů do leva s tím,že na první místo se nastavuje příznak CARRY. Je to vlastně podobné jako násobení jen s tím rozdílem, že zde se nenastavuje CARRY po přetečení na osmém bitu, ale dle nastaveného CARRY se nastavuje nebo nenastavuje bit první. Nejlépe je to ukázat na příkladě:

128
64
32
16
8
4
2
1
#
1
0
1
1
0
1
0
0
LDA #$B4
0
1
1
0
1
0
0
z carry
ROL

Vše se chová jako při násobení .. a k čemu je příkaz ROL vhodný ??? jednoduché ... nechceme-li přijít při násobení o "vypadlý" bit , který jde do carry, použijeme příkaz ROL a CARRY si opět nastavíme zpět. v příkladě:

jsr $e544 ; vymaze obrazovku

lda #24 ; nastavi znakovou sadu
sta 53272 ; od adresy $2000

lda #1 ; vlozi znak A
sta $0400 ; na obrazovku

lda #%11110000 ; hodnotu 11110000 vlozime
sta $2008 ; na prvni radek pismene A ve znakove sade

sem lda $2008 ; vezmeme hodnotu do A
asl ; vynasobime v akumulatoru (vlastne diky nasobeni pouze nastavime CARRY bit)
rol $2008 ; na adrese provedeme posun do leva s nastavenym CARRY po prikazu ASL.
jmp sem

Příklad je ke stáhnutí zde


ROR - Rotate on right neboli rolujeme s bity do prava.

Tak čtete-li naše díly opravdu postupně a pochopili jste je všechny, nevím, zda-li má smysl vůbec příkaz ROR rozebírat. Bude myslím stačit, když řeknu, že ROR a LSR se má k sobě jako ROL a ASL ... tudíž chcete-li s bity rolovat do prava (rorovat :), použijete právě příkaz ROR.

128
64
32
16
8
4
2
1
#
1
0
1
1
0
1
0
0
LDA #$B4
z carry
1
0
1
1
0
1
0
ROR

 


Jestliže jste opravdu pochopili vše , co jsme zatím probírali ve všech lekcích včetně této, mám tu pro vás velmi jednoduchý prográmek, kterým můžete prohlížet znakoou sadu počítače Commodore 64 pěkně převedenou do znaků... to vše pomocí všech příkazů, které jsme dnes probírali ...

Zdrojový kód prográmku prohlizec_znakove_rom.asm stahujte kliknutím

Po úspěšném přeassemblování a nahrátí do C64 nebo emulátoru spustíte prográmek příkazem SYS 4096

Pro ty, kteří chtějí videt pouze výsledný effekt ... stahujte zde ... ale prostudujte pořádně zdrojový kód výše .. opravdu to má cenu.

Nový příspěvek k článku

podpis :
První znak podpisu musí být vykřičník, jinak se příspěvek neodešle (ochrana proti spamu)

Advert

Programmed by PCH of UNREAL, Hardware support by RAY of UNREAL. Beta test and bugs guru SILLICON
Unreal 2014 - Czech republic