Operácie

ZPOC Online: 9. Pokračovanie v programovaní procesora

Z SensorWiki

Verzia z 22:38, 14. november 2020, ktorú vytvoril Balogh (diskusia | príspevky) (5. Vypočítajte dvojkový komplement čísla)

Tento týždeň pokračujeme prácou s trocha náročnejšími programami.

5. 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 E.


                             .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?

6. Test, či je číslo v pamäti nula

Pred delením musíme skontrolovať, či deliteľ na adrese 0020h náhodou nie je nula.

0020                          ORG   0020h   
0020   03                     DB   03h   

0000                          ORG   0000h   
0000   06 00                  MVI   B,00h      ; Do B si odlozime to co ideme testovat 
0002   3A 20 00               LDA   0020h      ; Do A nacitame cislo ktore ideme testovat
0005   B8                     CMP   B          ; test: je  Akumulator = B, teda 0?
0006   CA 0B 00               JZ    JeToNula   ; Ano, je to tak 
0009   00         NIEJENULA:  NOP              ; Tuto skoncime
000A   76                     HLT      
000B   00         JETONULA:   NOP              ; Nie, nie je to tak
000C   76                     HLT


7. 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

8. 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


Pre hĺbavejších študentov sú určené nasledovné dva programy:

9. 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

A. 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
  1. Skopírujte (presuňte) obsah pamäťového miesta 71h na adresu 72h.
  2. Na adresu 75h vložte hodnotu 1 (01b, 1 desiatkovo, 01h, nie ASCII).
  3. Vypočítajte dvojkový doplnok z čísla uloženého na adrese 73h a výsledok uložte do 74h
  4. Odčítajte od 71h obsah 72h a výsledok zapíšte späť do 71h
  5. Sčítajte obsah pamäťových miest 71h a 75h a výsledok uložte do 72h
  6. 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

1 Aký bude obsah registra B po vykonaní celého programu?

2 Aký bude obsah registra A po vykonaní celého programu?