Operácie

ZPOC online: 8. Základy programovania v strojovom kóde: Rozdiel medzi revíziami

Z SensorWiki

(Vytvorená stránka „Tieto jednoduché programy budeme analyzovať v [https://www.asm80.com/ simulátore procesora 8080]. Pri práci je dobrou pomôckou tento [http://senzor.robotika.sk/zp/8…“)
 
 
(6 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 3: Riadok 3:
  
  
[[Súbor:Simulator8080.png]]
+
[[Súbor:Simulator8080a.png]]
 
+
[[Súbor:Simulator8080b.png]]
  
  
Riadok 33: Riadok 33:
 
== '''Presuny sem a tam''' ==
 
== '''Presuny sem a tam''' ==
  
Tento program nerobí nič užitočné, len presúva data hore dole pomocou rozličných inštrukcií.  
+
Tento program nerobí nič užitočné, len presúva data hore dole pomocou rozličných inštrukcií. Program je tu zámerne aj so strojovým kódom a adresami, takže sa nedá Copy/Paste do simulátora. Je to tak preto, že kopírovaním sa nič nenaučíte, je potrebné ten program naozaj napísať.  
  
 
<source lang="asm">
 
<source lang="asm">
  
        ORG 0000h  ; tu hovorime, ze program zacne od adresy 0
+
0000                          .ORG   0000h  ; tu hovorime, ze program zacne od adresy 0
 +
 
 +
0000  3E 07                  MVI  A,07h  ; A = 07h - uloz do akumulatora cislo 7
 +
0002  47                    MOV  B,A    ; B = A  - obsah akumulatora skopiruj aj do B
 +
0003  4A                    MOV  C,D    ; C = D  - neviem co je v D, ale skopiruj to do C
 +
0004  32 10 00              STA  0010h  ; A = [0010] - do akumulatora skopiruj to co je v pamati na adrese 0010
 +
0007  3E 00                  MVI  A,00h  ; A = 0, mozeme nahradit aj kratsim SUB A - cim vynulujeme A
 +
0009  32 11 00              STA  0011h  ; to je vlastne MOV [0011],A cize presun (skopiruj) to co je v A do pamate
 +
000C  3A 10 00              LDA  0010h  ; a toto je vlastne MOV A, [0010], cize presun z pamate do A
 +
000F  76                    HLT     
  
        MVI A,07h  ; A = 07h - uloz do akumulatora cislo 7
 
        MOV B,A    ; B = A  - obsah akumulatora skopiruj aj do B
 
        MOV C,D    ; C = D  - neviem co je v D, ale skopiruj to do C
 
        STA 0010h  ; A = [0010] - do akumulatora skopiruj to co je v pamati na adrese 0010
 
        MVI A, 00h  ; A = 0, mozeme nahradit aj kratsim SUB A - cim vynulujeme A
 
        STA 0011h  ; to je vlastne MOV [0011],A cize presun (skopiruj) to co je v A do pamate
 
        LDA 0010h  ; a toto je vlastne MOV A, [0010], cize presun z pamate do A
 
        HLT
 
 
</source>
 
</source>
 
 
 
  
 
== '''Súčet dvoch 8-bitových čísel''' ==
 
== '''Súčet dvoch 8-bitových čísel''' ==
  
 
Spočítajte dve 8-bitové čísla v pamäti.
 
Spočítajte dve 8-bitové čísla v pamäti.
Prvý aj druhý sčítanec sú uložené v pamäti, výsledok chceme vrátiť tiež do pamäte za oba sčítance.
+
Prvý aj druhý sčítanec sú uložené v pamäti [0010h] a [0011h], výsledok chceme vrátiť tiež do pamäte za oba sčítance, teda na adresu [0012h].
  
Odskúšajte pre rozličné vstupné data. Ako vieme, že výsledok je OK?
+
Odskúšajte pre rozličné vstupné data. Ako vieme, že výsledok je OK? Skúste aj také čísla, ktorými prekročíte rozsah. Čo sa stane?  
  
 
Po preklade spočítajte koľko bajtov zaberajú obe riešenia a koľko SC spotrebujú.
 
Po preklade spočítajte koľko bajtov zaberajú obe riešenia a koľko SC spotrebujú.
Riadok 73: Riadok 71:
 
000B  76                    HLT
 
000B  76                    HLT
 
</source>
 
</source>
 +
 +
Tu je nepovinná ukážka, ako sa to dá spraviť aj celkom inak. Sú tam však inštrukcie, ktoré prekračujú rámec povinností na cvičeniach.
  
 
<source lang="asm">
 
<source lang="asm">
                              ORG 0010H   
+
0010                          .ORG   0010H   
                              DB 02H,03H,00H
+
0010  02 03 00              DB   02H,03H,00H   
                               
 
                              ORG 0000    
 
                              LXI H, 0010h      ; do HL adresu prveho cisla na adrese 0010
 
                              MOV A,M          ; do Akumulatora prve cislo z adresy {HL}
 
                              INX H            ; HL <-- HL + 1
 
                              ADD M            ; A <-- A + {HL}
 
                              INX H            ; HL <-- HL + 1
 
                              MOV M,A          ; uloz do pamate {HL}
 
                              HLT
 
</source>
 
 
 
 
 
== '''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.
 
  
<source lang="asm">
+
0000                          .ORG   0000 
            .ORG   0010H
+
0000  21 10 00              LXI  H,0010h    ; do HL adresu prveho cisla na adrese 0010
            DB      03H,02H,00H                ; tri cisla v pamati, tretie je 0 rezervovana pre vysledok
+
0003  7E                    MOV  A,M        ; do Akumulatora prve cislo z adresy {HL}
 +
0004  23                    INX  H          ; HL <-- HL + 1
 +
0005  86                    ADD  M          ; A <-- A + {HL}
 +
0006  23                    INX  H          ; HL <-- HL + 1
 +
0007  77                    MOV  M,A        ; uloz do pamate {HL}
 +
0008  76                    HLT     
  
            .ORG    0000
 
            LXI    H,0010h                    ; do HL adresu prveho cisla na adrese 0010
 
            MOV    A,M                        ; do Akumulatora prve cislo z adresy {HL}
 
            INX    H                          ; HL <-- HL + 1
 
            CMP    M                          ; porovnaj {HL} a Akumulátor
 
            JNC    HOTOVO                      ; ak A > {HL} skoc na HOTOVO:
 
            MOV    A,M                        ; v opacnom pripade presun do A druhu hodnotu
 
HOTOVO:    INX    H                          ; HL <-- HL + 1
 
            MOV    M,A                        ; uloz vysledok na nasl. adresu
 
            HLT   
 
 
</source>
 
</source>
  
Inštrukcia CMP M nastaví F tak, ako keby bol obsah z M odpočítaný od obsahu A. Na rozdiel od SUB
+
== '''Výmena''' ==
však obsah Akumulátora ostáva nezmenený.
 
Ak A je obsah Akumulátora a X je obsah M, tak F je nastavené nasledovne:
 
  
  Zero = 1  if  A = X
+
V pamäti sú za sebou uložené dve čísla. Vymeňte ich navzájom.
  Zero = 0  if  A &ne; X
 
Carry = 1  if  A < X
 
Carry = 0  if  A &ge; X
 
  
(A a X chápeme ako neznamienkové binárne čísla)
+
Pred spustením programu
  
 +
0010 42
 +
0011 55
  
=='''Spočítajte N čísel''' ==
+
Po vykonaní programu
  
Spočítajte N čísel so začiatkom na adrese 031h, pričom ich počet je na 030h.
+
0010 55
Výsledok uložte na 040h.
+
0011 42
  
<source lang="asm">
+
Program môže vyzerať napríklad takto, znova je vo formáte, ktorý sa nedá Copy/Paste do simulátora. Viete prečo...
            .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
 
</source>
 
 
 
== '''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.
 
  
 
<source lang="asm">
 
<source lang="asm">
            .org   0020H
+
0010                          .ORG  0010h    
            db    03h,02h,03h,01h   ; tri cisla = { 02, 03, 01 }
+
0010  42 55                  DB   42h,55h 
           
+
            .org   0000  
+
0000                          .ORG   0000h 
            lda    0020H
+
0000   3A 10 00              LDA  0010h    ; 1: precitaj do A z 010h
            mov    C,A               ; Initialize counter
+
0003  47                    MOV  B,A       ; 2: odloz A do B
            sub    A                 ; Maximum = Minimum possible value = 0
+
0004  3A 11 00              LDA  0011h    ; 3: precitaj do A z 011h
            lxi    H,0021H          ; Initialize pointer
+
0007  32 10 00              STA  0010h    ; 4: to rovno zapisem do 010h
BACK:       cmp    M                ; Is number > maximum
+
000A  78                    MOV  A,B      ; 5: vrat do A to z B
            jnc    SKIP              ; Yes, replace maximum
+
000B  32 11 00              STA  0011h    ; 6: zapis to do 011h
            mov    A,M
+
000E  76                    HLT             ; - hotovo
SKIP:       inx    H
 
            dcr    C
 
            jnz    BACK
 
            sta    0040H            ; Store maximum number
 
 
 
             HLT                      ; Terminate program execution
 
 
</source>
 
</source>
 
 
== Úlohy na samostatnú prácu ==
 
 
Jednotlivé úlohy riešte postupne a spájajte ich do jedného komplexného programu. Za každú vyriešenú úlohu ktorú ukážete cvičiacemu získavate 1 bod.
 
 
# Vynulujte 5 bajtov pamäte od adresy 070h
 
# Odložte do pamäte na adresu 70h až 74h hodnoty 1 až 5.
 
# Vymeňte obsah pamäťových miest 70h a 73h.
 
# Sčítajte obsah pamäťových miest 72h a 73h a výsledok uložte do 74h
 
# Odčítajte od 74h obsah 71h a zapíšte späť do 74h
 
# Nájdite dvojkový doplnok čísla z 72h
 
  
 
== Linky ==
 
== Linky ==

Aktuálna revízia z 15:06, 16. november 2020

Tieto jednoduché programy budeme analyzovať v simulátore procesora 8080. Pri práci je dobrou pomôckou tento ťahák s výberom inštrukcií. Obsluhu simulátora sme vysvetlili na cvičeniach, preto tu nájdete len tento stručný obrázok s opisom.


Simulator8080a.png Simulator8080b.png


Nulovanie pamäťového miesta

Vynulujte obsah pamäťového miesta 0010h, do ktorého sme vložili naschvál nejaké číslo (55h), aby ste vedeli skontrolovať, že program naozaj danú pamäťovú bunku vynuluje. Obsah pamäte môžete meniť aj ručne.

V prvom stĺpci je intuitívne riešenie, na ktoré asi prídete hneď - má dĺžku 5 Bajtov a trvá 20 strojových cyklov. V druhom stĺpci je profesionálnejšie riešenie, ktoré je kratšie (4B, 17T) a aj nastaví príznaky. V treťom stĺpci je riešenie pomocou pseudoinštrukcie EQU, ktorá zjednoduší a sprehľadní programovanie. Porovnajte.

POZN.: toto sú programy napísané pre porovnanie vedľa seba, do simulátora musíte napísať len jeden zo stĺpcov, takže Copy/Paste odtiaľto vám nebude fungovať!

                              myData  equ 0010h
  org 0010h       org 0010h           org myData
  db 55h          db 55h              db 55              ; nejake data aby sme mali co vymazat
             
  org 0000h       org 0000h           org 0000h          ; program uloz od 0000h
  mvi a,00h       sub A               sub A              ; najprv vynulujem akumulator   sub A: A <- A-A = 0
  sta 0010h       sta 0010h           sta myData         ; a potom ho presuniem do pamäte     
  hlt             hlt                 hlt                ; stop, koniec


Presuny sem a tam

Tento program nerobí nič užitočné, len presúva data hore dole pomocou rozličných inštrukcií. Program je tu zámerne aj so strojovým kódom a adresami, takže sa nedá Copy/Paste do simulátora. Je to tak preto, že kopírovaním sa nič nenaučíte, je potrebné ten program naozaj napísať.

0000                          .ORG   0000h   ; tu hovorime, ze program zacne od adresy 0

0000   3E 07                  MVI   A,07h   ; A = 07h - uloz do akumulatora cislo 7
0002   47                     MOV   B,A     ; B = A   - obsah akumulatora skopiruj aj do B
0003   4A                     MOV   C,D     ; C = D   - neviem co je v D, ale skopiruj to do C
0004   32 10 00               STA   0010h   ; A = [0010] - do akumulatora skopiruj to co je v pamati na adrese 0010
0007   3E 00                  MVI   A,00h   ; A = 0, mozeme nahradit aj kratsim SUB A - cim vynulujeme A
0009   32 11 00               STA   0011h   ; to je vlastne MOV [0011],A cize presun (skopiruj) to co je v A do pamate
000C   3A 10 00               LDA   0010h   ; a toto je vlastne MOV A, [0010], cize presun z pamate do A
000F   76                     HLT

Súčet dvoch 8-bitových čísel

Spočítajte dve 8-bitové čísla v pamäti. Prvý aj druhý sčítanec sú uložené v pamäti [0010h] a [0011h], výsledok chceme vrátiť tiež do pamäte za oba sčítance, teda na adresu [0012h].

Odskúšajte pre rozličné vstupné data. Ako vieme, že výsledok je OK? Skúste aj také čísla, ktorými prekročíte rozsah. Čo sa stane?

Po preklade spočítajte koľko bajtov zaberajú obe riešenia a koľko SC spotrebujú.

0010                          ORG 0010H   
0010   02 03 00               DB  02H,03H,00H    ; tri cisla v pamati, tretie je 0 rezervovana pre vysledok
   
0000                          ORG 0000      
0000   3A 0D 00               LDA  0010H         ; do Akumulatora prve cislo z adresy 0010
0003   47                     MOV  B,A           ; presun zatial do B
0004   3A 0E 00               LDA  0011H         ; do Akumulatora druhe cislo z nasledujucej adresy
0007   80                     ADD  B             ; A <-- A + B
0008   32 0F 00               STA  0012H         ; vysledok odloz na nasledujucu adresu 
000B   76                     HLT

Tu je nepovinná ukážka, ako sa to dá spraviť aj celkom inak. Sú tam však inštrukcie, ktoré prekračujú rámec povinností na cvičeniach.

0010                          .ORG   0010H   
0010   02 03 00               DB   02H,03H,00H   

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   86                     ADD   M           ; A <-- A + {HL}
0006   23                     INX   H           ; HL <-- HL + 1
0007   77                     MOV   M,A         ; uloz do pamate {HL}
0008   76                     HLT

Výmena

V pamäti sú za sebou uložené dve čísla. Vymeňte ich navzájom.

Pred spustením programu

0010 42
0011 55

Po vykonaní programu

0010 55
0011 42

Program môže vyzerať napríklad takto, znova je vo formáte, ktorý sa nedá Copy/Paste do simulátora. Viete prečo...

0010                          .ORG   0010h   
0010   42 55                  DB   42h,55h  
 
0000                          .ORG   0000h   
0000   3A 10 00               LDA   0010h     ; 1: precitaj do A z 010h
0003   47                     MOV   B,A       ; 2: odloz A do B
0004   3A 11 00               LDA   0011h     ; 3: precitaj do A z 011h
0007   32 10 00               STA   0010h     ; 4: to rovno zapisem do 010h
000A   78                     MOV   A,B       ; 5: vrat do A to z B
000B   32 11 00               STA   0011h     ; 6: zapis to do 011h
000E   76                     HLT             ; - hotovo

Linky


Precvičovanie

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?


Preštudujte si nasledovný program:

            ORG     0040h 
            DB      01h,03h,05h,07h 

            ORG     0000h 
            LDA     0041h 
            MOV     B,A 
            LDA     0040h 
            ADD     B 
            STA     0042h 
            HLT

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

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

3 Aký bude obsah pamäťového miesta s adresou 0043h po vykonaní celého programu?

4 Aký bude obsah pamäťového miesta s adresou 0042h po vykonaní celého programu?

Preštudujte si nasledovný program:

            ORG     0040h 
            DB      01h,03h,05h,07h 

            ORG     0000h 
            LDA     0043h 
            MOV     B,A 
            LDA     0042h 
            SUB     B 
            STA     0041h 
            SUB     A 
            STA     0040h 
            HLT

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

2 Aký bude obsah pamäťového miesta s adresou 0041h po vykonaní celého programu?

3 Aký bude stav príznaku Z (Zero) po vykonaní celého programu?

0
1

4 Aký bude obsah pamäťového miesta s adresou 0040h po vykonaní celého programu?