ZPOC Online: 9. Pokračovanie v programovaní procesora
Zo stránky SensorWiki
Tento týždeň pokračujeme prácou s trocha náročnejšími programami.
Vypočítajte dvojkový komplement čísla
V registri D máme čislo, ktorého dvojkový doplnok by sme chceli vypočítať. Výsledok uložíme do registra C.
.ORG 0000
0000 16 03 MVI D,03h
0002 7A MOV A,D
0003 2F CMA
0004 3C INR A
0005 5F MOV E,A
0006 76 HLT
Ako skúšku správnosti spravte naviac súčet výsledku a pôvodného čísla. Čo dostanete?
Nájdi väčšie z dvoch čísel
V pamäti sú za sebou uložené dve čísla. Nájdi väčšie z nich a ulož ho na ďalšiu pozíciu v pamäti.
0010 ORG 0010H
0010 03 02 00 DB 02H,04H,00H ; tri cisla v pamati, tretie je 0 rezervovana pre vysledok
0000 ORG 0000
0000 3A 10 00 LDA 0010h ; do Akumulatora prve cislo z adresy 0010h
0003 47 MOV B,A ; odlozime do B
0004 3A 11 00 LDA 0011h ; do Akumulatora druhe cislo z adresy 0011h
0007 B8 CMP B ; porovnaj B a Akumulátor
0008 D2 0C 00 JNC HOTOVO ; ak A > B skoc na HOTOVO:
000B 78 MOV A,B ; v opacnom pripade presun do A druhu hodnotu
000C 32 12 00 HOTOVO: STA 0012h ; uloz vysledok na nasl. adresu
000F 76 HLT
Inštrukcia CMP B spraví simulovaný rozdiel. Teda nastaví register F tak, ako keby bol obsah z B odpočítaný od obsahu A. Na rozdiel od inštrukcie SUB B však obsah Akumulátora ostáva nezmenený. Zhrnutie: Príznaky F sú nastavené nasledovne:
Zero = 1 if A = B Zero = 0 if A ≠ B Carry = 1 if A < B Carry = 0 if A ≥ B
(A a B chápeme ako neznamienkové binárne čísla)
Poznámka: Ak by to niekoho zaujímalo, tak na presuny medzi pamäťou a procesorom existujú aj trocha efektívnejšie inštrukcie a postupy. Napríklad by to mohlo vyzerať takto:
0010 ORG 0010H
0010 03 02 00 DB 03H,02H,00H ; tri cisla v pamati, tretie je 0 rezervovana pre vysledok
0000 ORG 0000
0000 21 10 00 LXI H,0010h ; do HL adresu prveho cisla na adrese 0010
0003 7E MOV A,M ; do Akumulatora prve cislo z adresy {HL}
0004 23 INX H ; HL <-- HL + 1
0005 BE CMP M ; porovnaj {HL} a Akumulátor
0006 D2 0A 00 JNC HOTOVO ; ak A > {HL} skoc na HOTOVO:
0009 7E MOV A,M ; v opacnom pripade presun do A druhu hodnotu
000A 23 HOTOVO: INX H ; HL <-- HL + 1
000B 77 MOV M,A ; uloz vysledok na nasl. adresu
000C 76 HLT
Vynásobenie dvoch čísel
Toto bude príklad na celkom jednoduché násobenie, nebudeme riešiť ani záporné čísla ani pretečenie.
Vynásobte dve čísla, uložené na adresách 0041h a 0042h. Výsledok uložte na 0040h.
0040 ORG 0040h
0040 03 04 00 DB 00h,03h,04h
0000 ORG 0000h
0000 06 00 MVI B,00 ; sem do B si budeme ukladat medzivysledky
0002 1E 00 MVI E,00 ; toto je nula, ktoru budeme testovat
0004 3A 40 00 LDA 0041h ; prvy cinitel z pamati do A
0007 57 MOV D,A ; odlozime si ho do D
0008 3A 41 00 LDA 0042h ; druhy cinitel z pamati do A
000B 4F SEM: MOV C,A ; odlozime si ho do C - counter
000C BB CMP E ; test: je uz Akumulator = E, teda 0?
000D CA 18 00 JZ KONIEC ; ak ano, tak uz mame hotovo
; ak nie, pripocitame dalsi krat
0010 78 MOV A,B ; v B mame medzivysledok, presunieme do A
0011 82 ADD D ; pripocitame znova D
0012 47 MOV B,A ; a odlozime medzisucet spat do B
0013 79 MOV A,C ; teraz kukneme na pocitadlo
0014 3D DCR A ; odpocitame jednotku
0015 C3 0B 00 JMP SEM ; a pokracujeme znova
0018 78 KONIEC: MOV A,B ; ak sme sa dostali az sem, tak medzivysledok
0019 32 42 00 STA 0040h ; ulozime na spravne miesto do pamati
001C 76 HLT
Spočítajte N čísel
Spočítajte N čísel so začiatkom na adrese 031h, pričom ich počet je na 030h. Výsledok uložte na 040h.
.ORG 0030h
DB 03h,01h,02h,03h
.ORG 0000
LDA 0030H
MOV C,A ; Initialize C-counter
SUB A ; sum = 0
LXI H,0031H ; Initialize pointer
BACK: ADD M ; SUM = SUM + data
INX H ; increment pointer
DCR C ; Decrement counter
JNZ BACK ; if counter 0 repeat
STA 040H ; Store sum
HLT ; Terminate program execution
Nájdi maximum v bloku hodnôt.
V pamäti je uložený blok dát. Prvé číslo v bloku je počet dát, nasleduje neusporiadaná množina 8-bitových hodnôt.
.org 0020H
db 03h,02h,03h,01h ; tri cisla = { 02, 03, 01 }
.org 0000
lda 0020H
mov C,A ; Initialize counter
sub A ; Maximum = Minimum possible value = 0
lxi H,0021H ; Initialize pointer
BACK: cmp M ; Is number > maximum
jnc SKIP ; Yes, replace maximum
mov A,M
SKIP: inx H
dcr C
jnz BACK
sta 0040H ; Store maximum number
HLT ; Terminate program execution
Domáca úloha
Naprogramujte postupne zadané úlohy. Riešte ich postupne a spájajte ich do jedného komplexného programu. Ak si myslíte, že váš program je už hotový (alebo ak už viac neviete spraviť), vyplňte v Classroome formulár, do ktorého vyplníte stav registrov v ktorom ste skončili.
Najprv do pamäte na adresy 70h až 74h vložte hodnoty zodpovedajúce ASCII kódom prvých piatich písmen vášho krstného mena. Pou6ite všetky písmená veľké
Napríklad pre mňa by obsah pamäte vyzeral takto
0068 00 00 00 00 | 00 00 00 00 0070 52 49 43 48 | 41 00 00 00 0078 00 00 00 00 | 00 00 00 00
- Skopírujte (presuňte) obsah pamäťového miesta 71h na adresu 72h.
- Na adresu 75h vložte hodnotu 1 (01b, 1 desiatkovo, 01h, nie ASCII).
- Vypočítajte dvojkový doplnok z čísla uloženého na adrese 73h a výsledok uložte do 74h
- Odčítajte od 71h obsah 72h a výsledok zapíšte späť do 71h
- Sčítajte obsah pamäťových miest 71h a 75h a výsledok uložte do 72h
- Sčítajte obsah pamäťových miest 73h a 74h a výsledok uložte do 73h
[72] <- [71] [75] <- 1 [74] <- ~[73] [71] <- [71] - [72] [72] <- [71] + [75] [73] <- [73] + [74]
Keď skončíte, vložte do formulára odpoveď na otázky:
[70] = ? [71] = ? [72] = ? [73] = ?
Flag Z = ? Flag P = ?
Poznámka: Ak budete ASCII hodnoty vkladať do pamäte pomocou pseudoinštrukcie DB, dávajte pri simulácii pozor, pretože tieto hodnoty sa tam vložia len raz, pri zapnutí emulátora (F10). Ak spustíte program druhý raz, napríklad po stlačení RST, v pamäti ostanú hodnoty tak, ako ste ich tam zanechali. Ak chcete mať znova vložené správne hodnoty, musíte sa prepnúť do editora a späť.
Linky
Precvičovanie
!!! TODO: pripravit nove ulohy na precvicenie!!!
Preštudujte si nasledovný program:
ORG 0000h
MVI A,07h
MOV B,A
MVI A,03h
MOV C,A
HLT