Hlavní navigace

Specifika instrukční sady mikroprocesorů Intel 8086/8088 (2)

17. 9. 2024
Doba čtení: 50 minut

Sdílet

 Autor: Thomas Nguyen, podle licence: CC BY-SA 4.0
Zaměříme se na specifické instrukce, které byly na mikroprocesorech Intel 8086/8088 podporovány. Bude se v první řadě jednat o instrukce pro BCD aritmetiku a o „řetězcové instrukce“, které jsou pro platformu 8086 typické.

Obsah

1. Specifika instrukční sady mikroprocesorů Intel 8086/8088 (2)

2. Výpis osmibitové hexadecimální hodnoty na obrazovku

3. Instrukce XLAT

4. BCD aritmetika na čipech Intel 8086/8088

5. Operace součtu s využitím binární i BCD aritmetiky

6. Instrukce DAA po provedení operace rozdílu

7. Instrukce DAS po provedení operace rozdílu

8. BCD formát, v němž je každá cifra uložena v celém bajtu

9. Korekce výsledku na jedinou BCD cifru operací AAA

10. Operace součinu a podílu

11. Ukázka výpočtu součinu dvou osmibitových hodnot

12. BCD korekce po výpočtu součinu instrukcí AAM

13. Řetězcové a blokové operace podporované mikroprocesory Intel 8086/8088

14. Varianty řetězcových a blokových operací

15. Zápis několika po sobě jdoucích znaků do řetězce

16. Vylepšení předchozího příkladu: opakování instrukce STOSB CX-krát

17. Překlad řetězcových instrukcí s prefixem i bez prefixu

18. Obsah navazujícího článku

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Specifika instrukční sady mikroprocesorů Intel 8086/8088 (2)

V dnešním článku navážeme na úvodní část, přičemž se zaměříme na skutečně specifické instrukce, které byly na mikroprocesorech Intel 8086/8088 podporovány a v šestnáctibitovém a 32bitovém režimu musí být na platformě x86/x86–64(AMD64) podporovány dodnes, a to i na nejmodernějších čipech (ať již přímo nebo v emulované podobě). Bude se v první řadě jednat o instrukce pro BCD aritmetiku (dvě formy, takzvaná „ASCII BCD“ a „packed BCD“) a o „řetězcové instrukce“, které jsou pro platformu 8086 zcela typické a nutno říci, že zjednodušují vývoj v assembleru a zkracují, popř. i zrychlují výsledný strojový kód. Nezapomeneme ale ani na zajímavou instrukci XLAT.

Demonstrační příklady, které budou uvedeny v navazujících kapitolách, jsou založeny na následující šabloně, v níž je definován formát výstupního souboru i podporovaná instrukční sada (jen 8086/8088). Navíc jsou v šabloně definována makra pro ukončení procesu, pro čekání na stisk klávesy (služba BIOSu) a taktéž pro tisk řetězce na obrazovku (služba DOSu):

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        print message
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db 0x01, 0x01, 0x0d, 0x0a, "$"
Poznámka: znaky s ASCII kódem 0×01, které jsou vytisknuty, mají na IBM PC tvar obličeje.

U jednotlivých demonstračních příkladů si budeme uvádět i výsledný strojový kód (bajty ve druhém sloupci za číslem řádku). Ten vypadá pro naši šablonu následovně:

     1                                  BITS 16         ; 16bitovy vystup pro DOS
     2                                  CPU 8086        ; specifikace pouziteho instrukcniho souboru
     3
     4                                  ; ukonceni procesu a navrat do DOSu
     5                                  %macro exit 0
     6                                          ret
     7                                  %endmacro
     8
     9                                  ; vyprazdneni bufferu klavesnice a cekani na klavesu
    10                                  %macro wait_key 0
    11                                          xor     ax, ax
    12                                          int     0x16
    13                                  %endmacro
    14
    15                                  ; tisk retezce na obrazovku
    16                                  %macro print 1
    17                                          mov     dx, %1
    18                                          mov     ah, 9
    19                                          int     0x21
    20                                  %endmacro
    21
    22                                  ;-----------------------------------------------------------------------------
    23                                  org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
    24
    25                                  start:
    26                                          print message
    17 00000000 BA[0C00]            <1>  mov dx, %1
    18 00000003 B409                <1>  mov ah, 9
    19 00000005 CD21                <1>  int 0x21
    27                                          wait_key
    11 00000007 31C0                <1>  xor ax, ax
    12 00000009 CD16                <1>  int 0x16
    28                                          exit
     6 0000000B C3                  <1>  ret
    29
    30                                          ; retezec ukonceny znakem $
    31                                          ; (tato data jsou soucasti vysledneho souboru typu COM)
    32 0000000C 01010D0A24              message db 0x01, 0x01, 0x0d, 0x0a, "$"
Poznámka: tento výpis se povoluje přepínačem -l, za nímž je nutné uvést jméno souboru, do kterého se má výpis (listing) zapsat.

2. Výpis osmibitové hexadecimální hodnoty na obrazovku

V dalších příkladech budeme pracovat s numerickými hodnotami, takže si ukažme, jakým způsobem lze na obrazovku vytisknout osmibitovou hexadecimální hodnotu. Nebude to nijak těžké. Nejdříve si připravíme řetězec, který budeme tisknout, přičemž první dva znaky tohoto řetězce budeme nahrazovat hexa číslicemi 0–9, a-f. Následují dva znaky pro odřádkování a návrat na začátek řádku a znak dolaru, který řetězec ukončuje (v tomto se DOS „inspiroval“ systémem CP/M):

        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db 0x01, 0x01, 0x0d, 0x0a, "$"

Převod hodnoty 0–15 na hexadecimální číslici lze naprogramovat (to jsme si ukázali u ZX Spectra) nebo lze použít jednoduchou převodní tabulku. ASCII sada totiž po číslici „9“ nenavazuje znakem „A“ nebo „a“, takže v převodní tabulce (nebo programovém kódu) musíme realizovat „přeskok“:

        ; prevodni tabulka hodnoty 0-15 na ASCII znak
hex_digits db "0123456789abcdef"

Nyní se pokusíme převést první (vyšší) číslici uloženou v registru CL na ASCII znak a ten uložit do výše uvedeného řetězce message (zapisujeme do kódového segmentu :-). Postupně si připravíme hodnotu 0–15 v registru BX a využijeme adresovací režim popsaný minule:

        xor     bh, bh                ; vynulovat horni bajt offsetu
 
        mov     bl, cl                ; do BL se vlozi horni hexa cifra
        and     bl, 0xf0              ; není zapotřebí, jen naznačujeme, že se využijí horní 4 bity
        shr     bl, 1                 ; horní čtyři bity do dolních čtyř bitů
        shr     bl, 1
        shr     bl, 1
        shr     bl, 1
 
        mov     al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce

Výpis spodní číslice je jednodušší, neboť nemusíme použít bitové posuny:

        mov     bl, cl                ; do BL se vlozi dolni hexa cifra
        and     bl, 0x0f
        mov     al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce

Celý výše uvedený kód vložíme do subrutiny nebo do makra. Pro zajímavost použijeme makro (což ale v praxi znamená, že každé použití makra nám celý program „natáhne“ o cca 40 bajtů!):

; tisk hexadecimalni hodnoty
%macro print_hex 1
        mov     cl, %1                ; zapamatovat si predanou hodnotu
        xor     bh, bh                ; vynulovat horni bajt offsetu
 
        mov     bl, cl                ; do BL se vlozi horni hexa cifra
        and     bl, 0xf0              ; není zapotřebí, jen naznačujeme, že se využijí horní 4 bity
        shr     bl, 1
        shr     bl, 1
        shr     bl, 1
        shr     bl, 1
 
        mov     al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce
 
        mov     bl, cl                ; do BL se vlozi dolni hexa cifra
        and     bl, 0x0f
        mov     al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce
        print   message
%endmacro

Překlad výše uvedeného makra při jeho prvním použití (expanzi):

    48                                     print_hex 0x00
    24 00000000 B100                mov cl, %1
    25 00000002 30FF                xor bh, bh
    26
    27 00000004 88CB                mov bl, cl
    28 00000006 80E3F0              and bl, 0xf0
    29 00000009 D0EB                shr bl, 1
    30 0000000B D0EB                shr bl, 1
    31 0000000D D0EB                shr bl, 1
    32 0000000F D0EB                shr bl, 1
    33
    34 00000011 8A87[B600]          mov al, [hex_digits + bx]
    35 00000015 A2[B100]            mov [message], al
    36
    37 00000018 88CB                mov bl, cl
    38 0000001A 80E30F              and bl, 0x0f
    39 0000001D 8A87[B600]          mov al, [hex_digits + bx]
    40 00000021 A2[B200]            mov [message + 1], al
    41                              print message
    17 00000024 BA[B100]            mov dx, %1
    18 00000027 B409                mov ah, 9
    19 00000029 CD21                int 0x21

A takto vypadá úplný zdrojový kód dnešního druhého demonstračního příkladu:

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
; tisk hexadecimalni hodnoty
%macro print_hex 1
        mov     cl, %1                ; zapamatovat si predanou hodnotu
        xor     bh, bh                ; vynulovat horni bajt offsetu
 
        mov     bl, cl                ; do BL se vlozi horni hexa cifra
        and     bl, 0xf0              ; není zapotřebí, jen naznačujeme, že se využijí horní 4 bity
        shr     bl, 1
        shr     bl, 1
        shr     bl, 1
        shr     bl, 1
 
        mov     al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce
 
        mov     bl, cl                ; do BL se vlozi dolni hexa cifra
        and     bl, 0x0f
        mov     al, [hex_digits + bx] ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce
        print   message
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        print_hex 0x00
        print_hex 0x12
        print_hex 0xab
        print_hex 0xff
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db 0x01, 0x01, 0x0d, 0x0a, "$"
 
        ; prevodni tabulka hodnoty 0-15 na ASCII znak
hex_digits db "0123456789abcdef"

3. Instrukce XLAT

Ve skutečnosti je možné převod hexadecimální hodnoty na ASCII řetězec napsat i odlišným způsobem, konkrétně s využitím instrukce XLAT. Tato instrukce dokáže načíst hodnotu z adresy DS : [BX+AL] a uložit výsledek opět do registru AL. To znamená, že takto můžeme relativně snadno realizovat vyhledávací tabulky. Mimochodem: jedná se o jedinou instrukci, v níž je použit registr AL pro výpočet adresy.

Po malých úpravách (změna použitých registrů) bude makro pro převod osmibitové hodnoty na ASCII řetězec s hexadecimální variantou hodnoty vypadat následovně:

        mov     bx, hex_digits
        mov     cl, %1                ; zapamatovat si predanou hodnotu
 
        mov     al, cl                ; do AL se vlozi horni hexa cifra
        and     al, 0xf0              ; není zapotřebí, jen naznačujeme, že se využijí horní 4 bity
        shr     al, 1
        shr     al, 1
        shr     al, 1
        shr     al, 1
 
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce
 
        mov     al, cl                ; do BL se vlozi dolni hexa cifra
        and     al, 0x0f
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce

Pro úplnost si ukažme, jak vypadá celý zdrojový kód dnešního třetího demonstračního příkladu:

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
; tisk hexadecimalni hodnoty
%macro print_hex 1
        mov     bx, hex_digits
        mov     cl, %1                ; zapamatovat si predanou hodnotu
 
        mov     al, cl                ; do AL se vlozi horni hexa cifra
        and     al, 0xf0              ; není zapotřebí, jen naznačujeme, že se využijí horní 4 bity
        shr     al, 1
        shr     al, 1
        shr     al, 1
        shr     al, 1
 
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce
 
        mov     al, cl                ; do BL se vlozi dolni hexa cifra
        and     al, 0x0f
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce
 
        print   message
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        print_hex 0x00
        print_hex 0x12
        print_hex 0xab
        print_hex 0xff
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db 0x01, 0x01, 0x0d, 0x0a, "$"
 
        ; prevodni tabulka hodnoty 0-15 na ASCII znak
hex_digits db "0123456789abcdef"

4. BCD aritmetika na čipech Intel 8086/8088

Mikroprocesory řady Intel 8086 (a tím pádem i 8088) podporovaly provádění základních aritmetických operací s BCD hodnotami (Binary-Coded Decimal). V tomto případě osmibitové registry obsahují buď pouze jednu cifru (tj. hodnotu 0–9 z možného rozsahu 0–256) nebo dvojici desítkových cifer – první cifra je uložena v horních čtyřech bitech, druhá cifra pochopitelně v dolních čtyřech bitech). Maximální rozsah uložených hodnot tedy nebude 0–255, ale jen 0–99, ovšem výhodou je snadnější převod do tisknutelné podoby, snadné zvětšení počtu cifer atd. S BCD, především s jeho „komprimovanou“ podobou (tedy rozsah 0–99 v jednom bajtu) se setkáme jak v některých čipech (hodiny reálného času, řadiče sedmisegmentových displejů), tak i například v databázových systémech, v některých systémech pro zpracování měny atd.

Poznámka: když se nad způsobem uložení cifer zamyslíme, zjistíme, že naše makro pro tisk hexadecimálních hodnot bude beze změny pracovat i pro BCD; ostatně proto jsme si ho uváděli.

K dispozici jsou následující instrukce pro práci s BCD:

Instrukce Operand Stručný popis instrukce
AAA jedna cifra v bajtu úprava výsledku součtu na BCD tvar
AAS jedna cifra v bajtu úprava výsledku rozdílu na BCD tvar
DAA dvě cifry v bajtu úprava výsledku součtu na BCD tvar
DAS dvě cifry v bajtu úprava výsledku rozdílu na BCD tvar
AAM dvě cifry v bajtu úprava výsledku součinu na BCD tvar
AAD dvě cifry v bajtu úprava hodnoty před provedením operace dělení
Poznámka: všechny tyto instrukce si postupně ukážeme. Pouze poslední instrukce AAD bude popsána příště – je sice poněkud zvláštní, ovšem má i své praktické využití.

5. Operace součtu s využitím binární i BCD aritmetiky

Mikroprocesory 8086 se nepřepínají do „režimu binární aritmetiky“ a „režimu BCD“ tak, jako například MOS 6502. Namísto toho se po provedení nějaké aritmetické operace musí explicitně výsledek této operace upravit. Základem je instrukce DAA, která upraví výsledek součtu. Konkrétně to znamená, že pokud dojde k přetečení mezi čtvrtým a pátým bitem (což se nastaví jako jeden z příznaků) nebo je hodnota nižších čtyř bitů větší než 0×0f, přičte se k výsledku šestka, čímž se upraví spodní cifra a zvýší cifra horní. Podobně pokud je hodnota vyšší než 0×99 nebo došlo k přenosu, přičte se k výsledku 0×60. Po provedení instrukce DAA tedy bude registr AL obsahovat hodnotu 0–99 zakódovanou jako dvojici BCD cifer.

Vyzkoušejme si to na čtveřici operací – vždy dvě budou provedeny s binárními hodnotami a dvě s BCD hodnotami:

        mov  al, 0x49
        inc  al
        print_hex al    ; vytiskne se 4a (binární)
 
        mov  al, 0x49
        inc  al
        daa
        print_hex al    ; vytiskne se 50 (korektní BCD)
 
        mov  al, 0x99
        inc  al
        print_hex al    ; vytiskne se 9a (binární)
 
        mov  al, 0x99
        inc  al
        daa
        print_hex al    ; vytiskne se 00 (korektní BCD, došlo k přetečení, takže vlastně 100)

Úplný zdrojový kód demonstračního příkladu vypadá takto:

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
; tisk hexadecimalni hodnoty
%macro print_hex 1
        mov     bx, hex_digits
        mov     cl, %1                ; zapamatovat si predanou hodnotu
 
        mov     al, cl                ; do AL se vlozi horni hexa cifra
        and     al, 0xf0
        shr     al, 1
        shr     al, 1
        shr     al, 1
        shr     al, 1
 
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce
 
        mov     al, cl                ; do BL se vlozi dolni hexa cifra
        and     al, 0x0f
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce
 
        print   message
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        mov  al, 0x49
        inc  al
        print_hex al
 
        mov  al, 0x49
        inc  al
        daa
        print_hex al
 
        mov  al, 0x99
        inc  al
        print_hex al
 
        mov  al, 0x99
        inc  al
        daa
        print_hex al
 
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db 0x01, 0x01, 0x0d, 0x0a, "$"
 
        ; prevodni tabulka hodnoty 0-15 na ASCII znak
hex_digits db "0123456789abcdef"

6. Instrukce DAA po provedení operace rozdílu

V předchozí kapitole jsme si řekli, že instrukce DAA slouží pro úpravu výsledku operace součtu na BCD tvar. Jak je tomu však ve chvíli, kdy provedeme DAA po operaci rozdílu? Na některých CPU bude výsledek korektní, takže si si zkusme:

        mov  al, 0x40
        sub  al, 1
        print_hex al    ; = 3f, což je korektní v binárním kódu
 
        mov  al, 0x40
        sub  al, 1
        daa
        print_hex al    ; = 45, což je v BCD špatně
 
        xor  al, al
        sub  al, 1
        print_hex al    ; = ff, což je korektní -1
 
        xor  al, al
        sub  al, 1
        daa
        print_hex al    ; = 65, což je v BCD špatně

Vidíme tedy, že instrukce DAA po operaci rozdílu nebo snížení hodnoty o 1 nedává korektní výsledky, i když nastavuje všechny potřebné příznaky.

Úplný zdrojový kód tohoto demonstračního příkladu vypadá následovně:

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
; tisk hexadecimalni hodnoty
%macro print_hex 1
        mov     bx, hex_digits
        mov     cl, %1                ; zapamatovat si predanou hodnotu
 
        mov     al, cl                ; do AL se vlozi horni hexa cifra
        and     al, 0xf0
        shr     al, 1
        shr     al, 1
        shr     al, 1
        shr     al, 1
 
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce
 
        mov     al, cl                ; do BL se vlozi dolni hexa cifra
        and     al, 0x0f
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce
 
        print   message
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        mov  al, 0x40
        sub  al, 1
        print_hex al
 
        mov  al, 0x40
        sub  al, 1
        daa
        print_hex al
 
        xor  al, al
        sub  al, 1
        print_hex al
 
        xor  al, al
        sub  al, 1
        daa
        print_hex al
 
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db 0x01, 0x01, 0x0d, 0x0a, "$"
 
        ; prevodni tabulka hodnoty 0-15 na ASCII znak
hex_digits db "0123456789abcdef"

7. Instrukce DAS po provedení operace rozdílu

Po provedení operace rozdílu je nutné pro získání korektního výsledku reprezentovaného v BCD použít instrukci DAS, která provádí podobné korekce jako DAA (na základě hodnoty horních a spodních čtyř bitů výsledku i příznaků), ovšem namísto toho, aby se k cifrám přičítaly hodnoty 6 a 0×60, se tyto hodnoty odečítají. Opět si tedy ověřme, zda kombinace SUB+DAS (nebo DEC+DAS) poskytne korektní BCD hodnotu:

        mov  al, 0x40
        sub  al, 1
        print_hex al    ; = 3f, což je korektní v binárním kódu
 
        mov  al, 0x40
        sub  al, 1
        das
        print_hex al    ; = 39, což je v BCD dobře
 
        xor  al, al
        sub  al, 1
        print_hex al    ; = ff, což je korektní -1
 
        xor  al, al
        sub  al, 1
        das
        print_hex al    ; = 99, což je v BCD dobře (0-1 = 99-100)

Pro jistotu si opět uveďme úplný zdrojový kód tohoto demonstračního příkladu:

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
; tisk hexadecimalni hodnoty
%macro print_hex 1
        mov     bx, hex_digits
        mov     cl, %1                ; zapamatovat si predanou hodnotu
 
        mov     al, cl                ; do AL se vlozi horni hexa cifra
        and     al, 0xf0
        shr     al, 1
        shr     al, 1
        shr     al, 1
        shr     al, 1
 
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce
 
        mov     al, cl                ; do BL se vlozi dolni hexa cifra
        and     al, 0x0f
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce
 
        print   message
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        mov  al, 0x40
        sub  al, 1
        print_hex al
 
        mov  al, 0x40
        sub  al, 1
        das
        print_hex al
 
        xor  al, al
        sub  al, 1
        print_hex al
 
        xor  al, al
        sub  al, 1
        das
        print_hex al
 
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db 0x01, 0x01, 0x0d, 0x0a, "$"
 
        ; prevodni tabulka hodnoty 0-15 na ASCII znak
hex_digits db "0123456789abcdef"

8. BCD formát, v němž je každá cifra uložena v celém bajtu

Mikroprocesory řady Intel 8086 podporovaly i BCD formát, ve kterém je každá cifra uložena v celém bajtu, tj. bajt může obsahovat pouze hodnoty 0 až 9, zbylých 245 možných hodnot je nevyužito. To pochopitelně představuje značné paměťové nároky, protože například hodnotu 10000 lze uložit do dvou bajtů při použití binárního formátu, do třech bajtů při použití „packed“ BCD, ovšem do celých pěti bajtu při použití zde popisovaného „unpacked“ formátu. Na druhou stranu je například převod hodnoty na ASCII triviální (přičtení konstanty nebo OR konstanty) a obejde se bez bitových posunů, maskování nebo dokonce provedení operace dělení.

Podobně jako pro „packed“ BCD existují instrukce pro korekci výsledku nazvané DAA a DAS, existuje pro „unpacked“ BCD dvojice instrukcí nazvaných AAA a AAS, tedy korekce po součtu, resp. rozdílu.

9. Korekce výsledku na jedinou BCD cifru operací AAA

Nejprve si ukažme korekci výsledku po součtu dvojice BCD hodnot (a je jedno, jestli ve formátu „packed“ nebo „unpacked“) instrukcí AAA. Výsledky porovnáme s korekční instrukcí DAA:

        mov  al, 8
        inc  al
        print_hex al   ; = 9 (korektní pro všechny formáty, protože cifra nepřetekla na (1)0)
 
        mov  al, 9
        inc  al
        print_hex al   ; = 0a (korektní pro binární formát)
 
        mov  al, 8
        inc  al
        daa
        print_hex al   ; = 9 (korektní pro všechny formáty, protože cifra nepřetekla na (1)0)
 
        mov  al, 9
        inc  al
        daa
        print_hex al   ; = 10 (korektní pro packed BCD)
 
        mov  al, 8
        inc  al
        aaa
        print_hex al   ; = 9 (korektní pro všechny formáty, protože cifra nepřetekla na (1)0)
 
        mov  al, 9
        inc  al
        aaa
        print_hex al   ; = 0 (korektní pro unpacked BCD - došlo k přetečení)
Poznámka: v posledním případě je nejenom nastaven příznak CF, ale navíc se i zvýší hodnota v registru AH o jedničku, což by bylo možné využít tehdy, pokud tento registr obsahuje další (vyšší) cifru.

A opět, jak je již zvykem, si uveďme celý příklad:

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
; tisk hexadecimalni hodnoty
%macro print_hex 1
        mov     bx, hex_digits
        mov     cl, %1                ; zapamatovat si predanou hodnotu
 
        mov     al, cl                ; do AL se vlozi horni hexa cifra
        and     al, 0xf0
        shr     al, 1
        shr     al, 1
        shr     al, 1
        shr     al, 1
 
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce
 
        mov     al, cl                ; do BL se vlozi dolni hexa cifra
        and     al, 0x0f
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce
 
        print   message
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        mov  al, 8
        inc  al
        print_hex al
 
        mov  al, 9
        inc  al
        print_hex al
 
        mov  al, 8
        inc  al
        daa
        print_hex al
 
        mov  al, 9
        inc  al
        daa
        print_hex al
 
        mov  al, 8
        inc  al
        aaa
        print_hex al
 
        mov  al, 9
        inc  al
        aaa
        print_hex al
 
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db 0x01, 0x01, 0x0d, 0x0a, "$"
 
        ; prevodni tabulka hodnoty 0-15 na ASCII znak
hex_digits db "0123456789abcdef"

10. Operace součinu a podílu

Čipy Intel 8086/8088 již patří do generace mikroprocesorů s implementovanou operací násobení a dělení (tedy součinu a podílu). Zde konkrétně se tyto operace rozlišují podle toho, zda se násobí osmibitové či 16bitové operandy (popř. dělí 32bitový dělitel nebo 16bitový dělitel) a zda má být operace provedena se znaménkem nebo bez znaménka. Tyto operace nejsou v žádném případě rychlé, což ostatně naznačuje i následující tabulka:

Instrukce Operace Doba trvání Stručný popis instrukce
MUL AX = AL * 8bit 70–77 součin bezznaménkových hodnot
MUL DX:AX = AX * 16bit 118–133 součin bezznaménkových hodnot
IMUL AX = AL * 8bit 80–98 součin hodnot se znaménkem
IMUL DX:AX = AX * 16bit 128–154 součin hodnot se znaménkem
       
DIV AL = AX / 8bit, AH = AX % 8bit 80–90 podíl (a zbytek) bezznaménkových hodnot
DIV AX = DX:AX / 16bit, DX = DX:AX % 16bit 144–162 podíl (a zbytek) bezznaménkových hodnot
IDIV AL = AX / 8bit, AH = AX % 8bit 101–112 podíl (a zbytek) hodnot se znaménkem
IDIV AX = DX:AX / 16bit, DX = DX:AX % 16bit 165–184 podíl (a zbytek) hodnot se znaménkem

I pro tyto operace existují „korekční“ instrukce pro BCD formát, jak si ukážeme níže a taktéž v navazujícím článku.

11. Ukázka výpočtu součinu dvou osmibitových hodnot

Vyzkoušejme si pro zajímavost vynásobit dvě osmibitové hodnoty. Víme již, že jeden z činitelů musí být uložen v registru AL a 16bitový výsledek bude uložen do registru AX. Násobení provedeme instrukcí MUL, což znamená, že jak operandy, tak i výsledek budou bezznaménkové:

        mov  al, 6
        mov  ah, 7
        mul  ah
        print_hex al

Výsledná vypsaná hodnota bude rovna 2A, což dekadicky skutečně znamená 42 (6×7).

Úplný zdrojový kód tohoto demonstračního příkladu vypadá následovně:

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
; tisk hexadecimalni hodnoty
%macro print_hex 1
        mov     bx, hex_digits
        mov     cl, %1                ; zapamatovat si predanou hodnotu
 
        mov     al, cl                ; do AL se vlozi horni hexa cifra
        and     al, 0xf0
        shr     al, 1
        shr     al, 1
        shr     al, 1
        shr     al, 1
 
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce
 
        mov     al, cl                ; do BL se vlozi dolni hexa cifra
        and     al, 0x0f
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce
 
        print   message
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        mov  al, 6
        mov  ah, 7
        mul  ah
        print_hex al
 
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db 0x01, 0x01, 0x0d, 0x0a, "$"
 
        ; prevodni tabulka hodnoty 0-15 na ASCII znak
hex_digits db "0123456789abcdef"

12. BCD korekce po výpočtu součinu instrukcí AAM

Po provedení násobení je výsledek uložen v binárním formátu, jak je to obvyklé. Můžeme ovšem provést nějakou korekci výsledku tak, aby byl součin transformován do BCD? Na platformě Intel 8086/8088 je to možné, protože tato platforma nabízí neobvyklou instrukci nazvanou AAM neboli ASCII Adjust After Multiply. Název této operace je poněkud matoucí, ovšem její funkce je relativně jednoduchá, protože se provedou tyto tři operace:

tmp := AL
AH := tmp / imm8
AL := tmp MOD imm8

přičemž platí, že se instrukce AAM přeloží tak, že druhý bajt instrukčního kódu obsahuje konstantu imm8 nastavenou na 10. To znamená, že AAM vypočítá nejnižší cifru výsledku a uloží ji do AL. Hodnotu výsledku podělenou deseti pak uloží do registru AH, takže opakovaným prováděním instrukce AAM můžeme získat jednotlivé cifry. Jednoduché řešení, že?

Poznámka: ruční úpravou (zakódováním) druhého bajtu instrukce lze realizovat například převody z osmičkové soustavy, ze soustavy dvanáctkové, šedesátkové (to je užitečné při práci s časem!) atd. Některé klony Intel 8086 však tento bajt neinterpretovaly, takže se jedná o obecně mírně nebezpečný trik.

Podívejme se nyní, jak získáme jednotlivé cifry výsledku operace 6×7. Víme, že se bude jednat o dvouciferný výsledek, takže pouze zobrazíme AL (nižší cifru) a potom AH (výsledek po vydělení 10, nyní přímo vyšší cifru):

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
; tisk hexadecimalni hodnoty
%macro print_hex 1
        mov     bx, hex_digits
        mov     cl, %1                ; zapamatovat si predanou hodnotu
 
        mov     al, cl                ; do AL se vlozi horni hexa cifra
        and     al, 0xf0
        shr     al, 1
        shr     al, 1
        shr     al, 1
        shr     al, 1
 
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message], al         ; zapis ASCII znaku do retezce
 
        mov     al, cl                ; do BL se vlozi dolni hexa cifra
        and     al, 0x0f
        xlat                          ; prevod hodnoty 0-15 na ASCII znak
        mov     [message + 1], al     ; zapis ASCII znaku do retezce
 
        print   message
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        mov  al, 6
        mov  ah, 7
        mul  ah      ; nasobek
        aam          ; naplni se AX
        shl ah, 1    ; vysuneme cifru do hornich 4 bitu
        shl ah, 1
        shl ah, 1
        shl ah, 1
        or  al, ah   ; spojime dve BCD cifry
        print_hex al
 
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db 0x01, 0x01, 0x0d, 0x0a, "$"
 
        ; prevodni tabulka hodnoty 0-15 na ASCII znak
hex_digits db "0123456789abcdef"

13. Řetězcové a blokové operace podporované mikroprocesory Intel 8086/8088

Zcela specifickou vlastností mikroprocesorů řady Intel 8086/8088 jsou instrukce určené pro provádění řetězcových a blokových operací. Tyto instrukce dokážou přečíst, popř. zapsat (popř. provést obě operace za sebou) bajt či slovo z adresy určené segmentovým a indexovým registrem, přičemž se příslušným způsobem upraví hodnota indexového registru: zvýší či sníží se o jedničku. Navíc lze prefixem REP (a jeho variantami) zajistit opakování těchto instrukcí, takže je například možné přenést celý řetězec či blok jedinou instrukcí. To znamená velkou úsporu místa (programový kód) a částečně i času (rychlejší provádění instrukcí), ovšem je nutné mít připraveny všechny adresy v příslušných registrech, mít korektně nastaven příznak určující, zda se mají adresy zvyšovat či snižovat a při opakování instrukcí je nutné mít i nastaveno počitadlo. A především – překladače vyšších programovacích jazyků musí být schopné tyto instrukce využít (což se zpočátku nedělo, takže tato vlastnost čipů Intel 8086 nebyla plně využívána).

14. Varianty řetězcových a blokových operací

V instrukčním souboru mikroprocesorů Intel 8086 nalezneme následující instrukce realizující řetězcové a blokové operace, popř. jejich nastavení:

Instrukce Stručný popis instrukce
CLD nastaví příznak DF pro určení směru přenosu (nahoru)
STD nastaví příznak DF pro určení směru přenosu (dolů)
   
LODSB načtení bajtu do AL z DS : [SI], zvýšení/snížení SI o 1
LODSW načtení slova do AX z DS : [SI], zvýšení/snížení SI o 2
STOSB uložení slova z AL do ES : [DI], zvýšení/snížení DI o 1
STOSW uložení slova z AL do ES : [DI], zvýšení/snížení DI o 2
MOVSB kombinace LODSB + STOSB v jediné instrukci
MOVSW kombinace LODSW + STOSW v jediné instrukci
   
CMPSB porovnání dvou bajtů z DS : [SI] a ES : [DI], zvýšení/snížení SI a DI
CMPSW porovnání dvou slov z DS : [SI] a ES : [DI], zvýšení/snížení SI a DI
SCASB nalezení bajtu v AL na adrese DS : [SI] (mění příznaky)
SCASW nalezení bajtu v AX na adrese DS : [SI] (mění příznaky)
   
INSB přečtení bajtu z portu, uložení na ES : [DI], zvýšení/snížení DI
OUTSB zápis bajtu na port z DS : [SI], zvýšení/snížení SI
   
REP/REPE/REPZ opakování další operace CX-krát
REPNE/REPNZ opakování další operace CX-krát, nebo až bude ZF==1

Jednotlivé instrukce i jejich varianty si pochopitelně postupně popíšeme. Taktéž se zmíníme o rychlosti provedení těchto operací, protože to může být v reálných programech kritickým místem.

15. Zápis několika po sobě jdoucích znaků do řetězce

Pokusme se nyní do následujícího řetězce:

        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db "Hello, world!", 0x0d, 0x0a, "$"

zapsat namísto prvního slova pětici hvězdiček, tj. výsledek by měl vypadat takto: „*****, world!\r\n!“

Tuto operaci lze provést následujícím způsobem:

  1. Do dvojice registrů ES:DI vložíme adresu prvního znaku (tedy znaku „H“)
  2. Do registru AL vložíme ASCII hodnotu hvězdičky
  3. (Měl by se nastavit i příznak DF, ten je však při startu korektní)
  4. Pětkrát zopakujeme instrukci STOSB, která vlastně provede mov ES, AL + inc DI

V assembleru to vypadá následovně (prozatím otrocky opíšeme STOSB pětkrát):

        push cs
        pop  es   ; ES:DI obsahuje adresu prvniho znaku ve zprave
        mov di, message
 
        mov al, "*"
 
        stosb     ; zapis hvezdicky a posun adresy
        stosb     ; zapis hvezdicky a posun adresy
        stosb     ; zapis hvezdicky a posun adresy
        stosb     ; zapis hvezdicky a posun adresy
        stosb     ; zapis hvezdicky a posun adresy

Výsledkem bude očekávaný řetězec, což si ostatně můžeme velmi snadno ověřit na reálném PC nebo v DOSBoxu překladem a spuštěním tohoto příkladu:

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        print message
 
        push cs
        pop  es   ; ES:DI obsahuje adresu prvniho znaku ve zprave
        mov di, message
 
        mov al, "*"
 
        stosb     ; zapis hvezdicky a posun adresy
        stosb     ; zapis hvezdicky a posun adresy
        stosb     ; zapis hvezdicky a posun adresy
        stosb     ; zapis hvezdicky a posun adresy
        stosb     ; zapis hvezdicky a posun adresy
 
        print message
 
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db "Hello, world!", 0x0d, 0x0a, "$"

16. Vylepšení předchozího příkladu: opakování instrukce STOSB CX-krát

Demonstrační příklad z předchozí kapitoly lze upravit takovým způsobem, aby se instrukce STOSB v kódu vyskytovala pouze jedenkrát. Postačuje před ní vložit prefixovou instrukci REP, která zajistí opakování CX-krát. Celý postup by tedy měl vypadat následovně:

  1. Do dvojice registrů ES:DI vložíme adresu prvního znaku (tedy znaku „H“)
  2. Do registru AL vložíme ASCII hodnotu hvězdičky
  3. (Měl by se nastavit i příznak DF, ten je však při startu korektní)
  4. Do registru CX vložíme konstantu 5
  5. Spustíme instrukci REP STOSB, která vlastně CX-krát provede mov ES, AL + inc DI

V assembleru lze tuto posloupnost instrukcí realizovat snadno:

        push cs
        pop  es   ; ES:DI obsahuje adresu prvniho znaku ve zprave
        mov di, message
 
        mov al, "*"
        mov cx, 5
        rep stosb ; zapis peti hvezdicek

Výsledek bude odpovídat předchozímu příkladu.

Pro úplnost si uveďme výpis zdrojového kódu, který je velmi krátký:

BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
; ukonceni procesu a navrat do DOSu
%macro exit 0
        ret
%endmacro
 
; vyprazdneni bufferu klavesnice a cekani na klavesu
%macro wait_key 0
        xor     ax, ax
        int     0x16
%endmacro
 
; tisk retezce na obrazovku
%macro print 1
        mov     dx, %1
        mov     ah, 9
        int     0x21
%endmacro
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        print message
 
        push cs
        pop  es   ; ES:DI obsahuje adresu prvniho znaku ve zprave
        mov di, message
 
        mov al, "*"
        mov cx, 5
        rep stosb ; zapis peti hvezdicek
 
        print message
 
        wait_key
        exit
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db "Hello, world!", 0x0d, 0x0a, "$"

17. Překlad řetězcových instrukcí s prefixem i bez prefixu

Zajímavé bude zjistit, jak jsou vlastně řetězcové instrukce zakódovány ve strojovém kódu a jak jejich kód ovlivňuje použití prefixu REP. Podívejme se tedy nejdříve na výpis strojového kódu příkladu s opakujícími se instrukcemi STOSB:

    22                                  ;-----------------------------------------------------------------------------
    23                                  org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
    24
    25                                  start:
    26                                          print message
    17 00000000 BA[1F00]            <1>  mov dx, %1
    18 00000003 B409                <1>  mov ah, 9
    19 00000005 CD21                <1>  int 0x21
    27
    28 00000007 0E                              push cs
    29 00000008 07                              pop  es   ; ES:DI obsahuje adresu prvniho znaku ve zprave
    30 00000009 BF[1F00]                        mov di, message
    31
    32 0000000C B02A                            mov al, "*"
    33
    34 0000000E AA                              stosb     ; zapis hvezdicky a posun adresy
    35 0000000F AA                              stosb     ; zapis hvezdicky a posun adresy
    36 00000010 AA                              stosb     ; zapis hvezdicky a posun adresy
    37 00000011 AA                              stosb     ; zapis hvezdicky a posun adresy
    38 00000012 AA                              stosb     ; zapis hvezdicky a posun adresy
    39
    40                                          print message
    17 00000013 BA[1F00]            <1>  mov dx, %1
    18 00000016 B409                <1>  mov ah, 9
    19 00000018 CD21                <1>  int 0x21
    41
    42                                          wait_key
    11 0000001A 31C0                <1>  xor ax, ax
    12 0000001C CD16                <1>  int 0x16
    43                                          exit
     6 0000001E C3                  <1>  ret
    44
    45                                          ; retezec ukonceny znakem $
    46                                          ; (tato data jsou soucasti vysledneho souboru typu COM)
    47 0000001F 48656C6C6F2C20776F-     message db "Hello, world!", 0x0d, 0x0a, "$"
    47 00000028 726C64210D0A24

Z výpisu je patrné, že tak složitá instrukce, jakou STOSB interně je, je zakódována jen jediným bajtem 0×aa.

Ve druhém kroku se podívejme na příklad s instrukcí REP STOSB:

    22                                  ;-----------------------------------------------------------------------------
    23                                  org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
    24
    25                                  start:
    26                                          print message
    17 00000000 BA[1F00]            <1>  mov dx, %1
    18 00000003 B409                <1>  mov ah, 9
    19 00000005 CD21                <1>  int 0x21
    27
    28 00000007 0E                              push cs
    29 00000008 07                              pop  es   ; ES:DI obsahuje adresu prvniho znaku ve zprave
    30 00000009 BF[1F00]                        mov di, message
    31
    32 0000000C B02A                            mov al, "*"
    33 0000000E B90500                          mov cx, 5
    34 00000011 F3AA                            rep stosb ; zapis peti hvezdicek
    35
    36                                          print message
    17 00000013 BA[1F00]            <1>  mov dx, %1
    18 00000016 B409                <1>  mov ah, 9
    19 00000018 CD21                <1>  int 0x21
    37
    38                                          wait_key
    11 0000001A 31C0                <1>  xor ax, ax
    12 0000001C CD16                <1>  int 0x16
    39                                          exit
     6 0000001E C3                  <1>  ret
    40
    41                                          ; retezec ukonceny znakem $
    42                                          ; (tato data jsou soucasti vysledneho souboru typu COM)
    43 0000001F 48656C6C6F2C20776F-     message db "Hello, world!", 0x0d, 0x0a, "$"
    43 00000028 726C64210D0A24

Z výpisu je patrné použití dvou bajtů s hodnotami 0×f3 0×aa. To opět není mnoho a jen to potvrzuje domněnku, že se mělo jednat o centrální instrukce čipu Intel 8086 (tyto instrukce jsou kratší, než běžné MOV nebo INC).

CS24 tip temata

18. Obsah navazujícího článku

V navazujícím článku dokončíme popis instrukčního souboru mikroprocesorů Intel 8086/8088. Zejména si doplníme informaci o řetězcových a blokových instrukcích (doby jejich provedení, některé optimalizace atd.) a taktéž se zmíníme o způsobu kódování instrukcí do strojového kódu.

19. Repositář s demonstračními příklady

Demonstrační příklady napsané v assembleru, které jsou určené pro překlad s využitím assembleru NASM, byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/8bit-fame. Jednotlivé demonstrační příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý (dnes již poměrně rozsáhlý) repositář:

# Příklad Stručný popis Adresa
1 hello.asm program typu „Hello world“ naprogramovaný v assembleru pro systém DOS https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello.asm
2 hello_shorter.asm kratší varianta výskoku z procesu zpět do DOSu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_shorter.asm
3 hello_wait.asm čekání na stisk klávesy https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_wait.asm
4 hello_macros.asm realizace jednotlivých částí programu makrem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hello_macros.asm
       
5 gfx4_putpixel.asm vykreslení pixelu v grafickém režimu 4 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_putpixel.asm
6 gfx6_putpixel.asm vykreslení pixelu v grafickém režimu 6 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel.asm
7 gfx4_line.asm vykreslení úsečky v grafickém režimu 4 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_line.asm
8 gfx6_line.asm vykreslení úsečky v grafickém režimu 6 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_line.asm
       
9 gfx6_fill1.asm vyplnění obrazovky v grafickém režimu, základní varianta https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill1.asm
10 gfx6_fill2.asm vyplnění obrazovky v grafickém režimu, varianta s instrukcí LOOP https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill2.asm
11 gfx6_fill3.asm vyplnění obrazovky instrukcí REP STOSB https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill3.asm
12 gfx6_fill4.asm vyplnění obrazovky, synchronizace vykreslování s paprskem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_fill4.asm
       
13 gfx4_image1.asm vykreslení rastrového obrázku získaného z binárních dat, základní varianta https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image1.asm
14 gfx4_image2.asm varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSB https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image2.asm
15 gfx4_image3.asm varianta vykreslení rastrového obrázku s využitím instrukce REP MOVSW https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image3.asm
16 gfx4_image4.asm korektní vykreslení všech sudých řádků bitmapy https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image4.asm
17 gfx4_image5.asm korektní vykreslení všech sudých i lichých řádků bitmapy https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image5.asm
       
18 gfx4_image6.asm nastavení barvové palety před vykreslením obrázku https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image6.asm
19 gfx4_image7.asm nastavení barvové palety před vykreslením obrázku, snížená intenzita barev https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image7.asm
20 gfx4_image8.asm postupná změna barvy pozadí https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx4_image8.asm
       
21 gfx6_putpixel1.asm vykreslení pixelu, základní varianta se 16bitovým násobením https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel1.asm
22 gfx6_putpixel2.asm vykreslení pixelu, varianta s osmibitovým násobením https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel2.asm
23 gfx6_putpixel3.asm vykreslení pixelu, varianta bez násobení https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel3.asm
24 gfx6_putpixel4.asm vykreslení pixelu přes obrázek, nekorektní chování (přepis obrázku) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel4.asm
25 gfx6_putpixel5.asm vykreslení pixelu přes obrázek, korektní varianta pro bílé pixely https://github.com/tisnik/8bit-fame/blob/master/pc-dos/gfx6_putpixel5.asm
       
26 cga_text_mode1.asm standardní textový režim s rozlišením 40×25 znaků https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode1.asm
27 cga_text_mode3.asm standardní textový režim s rozlišením 80×25 znaků https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode3.asm
28 cga_text_mode_intensity.asm změna významu nejvyššího bitu atributového bajtu: vyšší intenzita namísto blikání https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_intensity.asm
29 cga_text_mode_cursor.asm změna tvaru textového kurzoru https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_cursor.asm
30 cga_text_gfx1.asm zobrazení „rastrové mřížky“: pseudografický režim 160×25 pixelů (interně textový režim) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_gfx1.asm
31 cga_text_mode_char_height.asm změna výšky znaků https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_mode_char_height.asm
32 cga_text_160×100.asm grafický režim 160×100 se šestnácti barvami (interně upravený textový režim) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/cga_text_160×100.asm
       
33 hercules_text_mode1.asm využití standardního textového režimu společně s kartou Hercules https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode1.asm
34 hercules_text_mode2.asm zákaz blikání v textových režimech https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_text_mode2.asm
35 hercules_turn_off.asm vypnutí generování video signálu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_turn_off.asm
36 hercules_gfx_mode1.asm přepnutí karty Hercules do grafického režimu (základní varianta) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode1.asm
37 hercules_gfx_mode2.asm přepnutí karty Hercules do grafického režimu (vylepšená varianta) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_gfx_mode2.asm
38 hercules_putpixel.asm subrutina pro vykreslení jediného pixelu na kartě Hercules https://github.com/tisnik/8bit-fame/blob/master/pc-dos/hercules_putpixel.asm
       
39 ega_text_mode_80×25.asm standardní textový režim 80×25 znaků na kartě EGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×25.asm
40 ega_text_mode_80×43.asm zobrazení 43 textových řádků na kartě EGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_text_mode_80×43.asm
41 ega_gfx_mode_320×200.asm přepnutí do grafického režimu 320×200 pixelů se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_320×200.asm
42 ega_gfx_mode_640×200.asm přepnutí do grafického režimu 640×200 pixelů se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×200.asm
43 ega_gfx_mode_640×350.asm přepnutí do grafického režimu 640×350 pixelů se čtyřmi nebo šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_640×350.asm
44 ega_gfx_mode_bitplanes1.asm ovládání zápisu do bitových rovin v planárních grafických režimech (základní způsob) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes1.asm
45 ega_gfx_mode_bitplanes2.asm ovládání zápisu do bitových rovin v planárních grafických režimech (rychlejší způsob) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_gfx_mode_bitplanes2.asm
       
46 ega_320×200_putpixel.asm vykreslení pixelu v grafickém režimu 320×200 pixelů se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_320×200_putpixel.asm
47 ega_640×350_putpixel.asm vykreslení pixelu v grafickém režimu 640×350 pixelů se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_640×350_putpixel.asm
       
48 ega_standard_font.asm použití standardního fontu grafické karty EGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_standard_font.asm
49 ega_custom_font.asm načtení vlastního fontu s jeho zobrazením https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_custom_font.asm
       
50 ega_palette1.asm změna barvové palety (všech 16 barev) v grafickém režimu 320×200 se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette1.asm
51 ega_palette2.asm změna barvové palety (všech 16 barev) v grafickém režimu 640×350 se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette2.asm
52 ega_palette3.asm změna všech barev v barvové paletě s využitím programové smyčky https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette3.asm
53 ega_palette4.asm změna všech barev, včetně barvy okraje, v barvové paletě voláním funkce BIOSu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ega_palette4.asm
       
54 vga_text_mode_80×25.asm standardní textový režim 80×25 znaků na kartě VGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×25.asm
55 vga_text_mode_80×50.asm zobrazení 50 a taktéž 28 textových řádků na kartě VGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_80×50.asm
56 vga_text_mode_intensity1.asm změna chování atributového bitu pro blikání (nebezpečná varianta změny registrů) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity1.asm
57 vga_text_mode_intensity2.asm změna chování atributového bitu pro blikání (bezpečnější varianta změny registrů) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_intensity2.asm
58 vga_text_mode_9th_column.asm modifikace způsobu zobrazení devátého sloupce ve znakových režimech (720 pixelů na řádku) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_9th_column.asm
59 vga_text_mode_cursor_shape.asm změna tvaru textového kurzoru na grafické kartě VGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_cursor_shape.asm
60 vga_text_mode_custom_font.asm načtení vlastního fontu s jeho zobrazením https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_text_mode_custom_font.asm
       
61 vga_gfx_mode_640×480.asm přepnutí do grafického režimu 640×480 pixelů se šestnácti barvami, vykreslení vzorků https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_640×480.asm
62 vga_gfx_mode_320×200.asm přepnutí do grafického režimu 320×200 pixelů s 256 barvami, vykreslení vzorků https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×200.asm
63 vga_gfx_mode_palette.asm změna všech barev v barvové paletě grafické karty VGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_palette.asm
64 vga_gfx_mode_dac1.asm využití DAC (neočekávané výsledky) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac1.asm
65 vga_gfx_mode_dac2.asm využití DAC (očekávané výsledky) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac2.asm
       
66 vga_640×480_putpixel.asm realizace algoritmu pro vykreslení pixelu v grafickém režimu 640×480 pixelů se šestnácti barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_640×480_putpixel.asm
67 vga_320×200_putpixel1.asm realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (základní varianta) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel1.asm
68 vga_320×200_putpixel2.asm realizace algoritmu pro vykreslení pixelu v grafickém režimu 320×200 s 256 barvami (rychlejší varianta) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel2.asm
       
69 vga_gfx_mode_dac3.asm přímé využití DAC v grafickém režimu 13h https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_dac3.asm
       
70 vga_gfx_mode_unchained_step1.asm zobrazení barevných pruhů v režimu 13h https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step1.asm
71 vga_gfx_mode_unchained_step2.asm vypnutí zřetězení bitových rovin a změna způsobu adresování pixelů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step2.asm
72 vga_gfx_mode_unchained_step3.asm vykreslení barevných pruhů do vybraných bitových rovin https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_unchained_step3.asm
       
73 vga_gfx_mode_320×400.asm nestandardní grafický režim s rozlišením 320×400 pixelů a 256 barvami https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_gfx_mode_320×400.asm
74 vga_320×200_image.asm zobrazení rastrového obrázku ve standardním grafickém režimu 320×200 pixelů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image.asm
75 vga_320×200_unchained_image1.asm zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (nekorektní řešení) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image1.asm
76 vga_320×200_unchained_image2.asm zobrazení rastrového obrázku v režimu s nezřetězenými rovinami (korektní řešení) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_unchained_image2.asm
77 vga_320×400_unchained_image.asm zobrazení rastrového obrázku v nestandardním režimu 320×400 pixelů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_unchained_image.asm
       
78 vga_vertical_scroll1.asm vertikální scrolling na kartě VGA v režimu s rozlišením 320×200 pixelů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll1.asm
79 vga_vertical_scroll2.asm vertikální scrolling na kartě VGA v režimu s rozlišením 320×400 pixelů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_vertical_scroll2.asm
80 vga_split_screen1.asm režim split-screen a scrolling, nefunční varianta https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen1.asm
81 vga_split_screen2.asm režim split-screen a scrolling, plně funkční varianta https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_split_screen2.asm
82 vga_horizontal_scroll1.asm horizontální scrolling bez rozšíření počtu pixelů na virtuálním řádku https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll1.asm
83 vga_horizontal_scroll2.asm horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll2.asm
84 vga_horizontal_scroll3.asm jemný horizontální scrolling s rozšířením počtu pixelů na virtuálním řádku https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_horizontal_scroll3.asm
       
85 vga_320×240_image.asm nastavení grafického režimu Mode-X, načtení a vykreslení obrázku, scrolling https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_image.asm
       
86 io.asm knihovna maker pro I/O operace https://github.com/tisnik/8bit-fame/blob/master/pc-dos/io.asm
87 vga_lib.asm knihovna maker a podprogramů pro programování karty VGA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_lib.asm
88 vga_320×240_lib.asm nastavení grafického režimu Mode-X, tentokrát knihovními funkcemi https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×240_lib.asm
       
89 vga_bitblt1.asm první (naivní) implementace operace BitBLT https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt1.asm
90 vga_bitblt2.asm operace BitBLT s výběrem bitových rovin pro zápis https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt2.asm
91 vga_bitblt3.asm operace BitBLT s výběrem bitových rovin pro čtení i zápis https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt3.asm
92 vga_bitblt4.asm korektní BitBLT pro 16barevný režim, realizace makry https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt4.asm
93 vga_bitblt5.asm korektní BitBLT pro 16barevný režim, realizace podprogramem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt5.asm
       
94 vga_bitblt_rotate.asm zápisový režim s rotací bajtu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt_rotate.asm
95 vga_bitblt_fast.asm rychlá korektní 32bitová operace typu BitBLT https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_bitblt_fast.asm
96 vga_320×400_bitblt1.asm přenos obrázku v režimu 320×400 operací BitBLT (neúplná varianta) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_bitblt1.asm
97 vga_320×400_bitblt2.asm přenos obrázku v režimu 320×400 operací BitBLT (úplná varianta) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×400_bitblt2.asm
98 vga_write_modes1.asm volitelné zápisové režimy grafické karty VGA, zápis bez úpravy latche https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes1.asm
99 vga_write_modes2.asm volitelné zápisové režimy grafické karty VGA, zápis s modifikací latche https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes2.asm
100 vga_write_modes3.asm volitelné zápisové režimy grafické karty VGA, cílená modifikace latche vzorkem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_write_modes3.asm
       
101 instruction_jump.asm použití instrukce JMP https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jump.asm
102 instruction_jnz.asm použití instrukce JNZ pro realizaci programové smyčky https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jnz.asm
103 instruction_jz_jmp.asm použití instrukcí JZ a JMP pro realizaci programové smyčky https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_jz_jmp.asm
104 instruction_loop.asm použití instrukce LOOP pro realizaci programové smyčky https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_loop.asm
       
105 instruction_template.asm šablona všech následujících demonstračních příkladů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_template.asm
106 instruction_print_hex.asm tisk osmibitové hexadecimální hodnoty https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_print_hex.asm
107 instruction_xlat.asm využití instrukce XLAT pro získání tisknutelné hexadecimální cifry https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_xlat.asm
       
108 instruction_daa.asm operace součtu s využitím binární i BCD aritmetiky https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_daa.asm
109 instruction_daa_sub.asm instrukce DAA po provedení operace rozdílu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_daa_sub.asm
110 instruction_das.asm instrukce DAS po provedení operace rozdílu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_das.asm
111 instruction_aaa.asm korekce výsledku na jedinou BCD cifru operací AAA https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_aaa.asm
112 instruction_mul.asm ukázka výpočtu součinu dvou osmibitových hodnot https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_mul.asm
113 instruction_aam.asm BCD korekce po výpočtu součinu instrukcí AAM https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_aam.asm
       
114 instruction_stosb.asm blokový zápis dat instrukcí STOSB https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_stosb.asm
115 instruction_rep_stosb.asm opakované provádění instrukce STOSB https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_stosb.asm
116 instruction_lodsb.asm čtení dat instrukcí LODSB https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_lodsb.asm
117 instruction_movsb.asm přenos jednoho bajtu instrukcí MOVSB https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_movsb.asm
118 instruction_rep_movsb.asm blokový přenos po bajtech instrukcí MOVSB https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_movsb.asm
119 instruction_rep_scas.asm vyhledávání v řetězci instrukcí SCAS https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_rep_scas.asm

20. Odkazy na Internetu

  1. The Intel 8088 Architecture and Instruction Set
    https://people.ece.ubc.ca/~ed­c/464/lectures/lec4.pdf
  2. x86 Opcode Structure and Instruction Overview
    https://pnx.tf/files/x86_op­code_structure_and_instruc­tion_overview.pdf
  3. x86 instruction listings (Wikipedia)
    https://en.wikipedia.org/wi­ki/X86_instruction_listin­gs
  4. x86 assembly language (Wikipedia)
    https://en.wikipedia.org/wi­ki/X86_assembly_language
  5. Intel Assembler (Cheat sheet)
    http://www.jegerlehner.ch/in­tel/IntelCodeTable.pdf
  6. 25 Microchips That Shook the World
    https://spectrum.ieee.org/tech-history/silicon-revolution/25-microchips-that-shook-the-world
  7. Chip Hall of Fame: MOS Technology 6502 Microprocessor
    https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-mos-technology-6502-microprocessor
  8. Chip Hall of Fame: Intel 8088 Microprocessor
    https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-intel-8088-microprocessor
  9. Jak se zrodil procesor?
    https://www.root.cz/clanky/jak-se-zrodil-procesor/
  10. Apple II History Home
    http://apple2history.org/
  11. The 8086/8088 Primer
    https://www.stevemorse.or­g/8086/index.html
  12. flat assembler: Assembly language resources
    https://flatassembler.net/
  13. FASM na Wikipedii
    https://en.wikipedia.org/wiki/FASM
  14. Fresh IDE FASM inside
    https://fresh.flatassembler.net/
  15. MS-DOS Version 4.0 Programmer's Reference
    https://www.pcjs.org/docu­ments/books/mspl13/msdos/dos­ref40/
  16. INT 21 – DOS Function Dispatcher (DOS)
    https://www.stanislavs.or­g/helppc/int21.html
  17. DOS API (Wikipedia)
    https://en.wikipedia.org/wiki/DOS_API
  18. Bit banging
    https://en.wikipedia.org/wi­ki/Bit_banging
  19. IBM Basic assembly language and successors (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Basic_assembly_lan­guage_and_successors
  20. X86 Assembly/Bootloaders
    https://en.wikibooks.org/wi­ki/X86_Assembly/Bootloaders
  21. Počátky grafiky na PC: grafické karty CGA a Hercules
    https://www.root.cz/clanky/pocatky-grafiky-na-pc-graficke-karty-cga-a-hercules/
  22. Co mají společného Commodore PET/4000, BBC Micro, Amstrad CPC i grafické karty MDA, CGA a Hercules?
    https://www.root.cz/clanky/co-maji-spolecneho-commodore-pet-4000-bbc-micro-amstrad-cpc-i-graficke-karty-mda-cga-a-hercules/
  23. Karta EGA: první použitelná barevná grafika na PC
    https://www.root.cz/clanky/karta-ega-prvni-pouzitelna-barevna-grafika-na-pc/
  24. RGB Classic Games
    https://www.classicdosgames.com/
  25. Turbo Assembler (Wikipedia)
    https://en.wikipedia.org/wi­ki/Turbo_Assembler
  26. Microsoft Macro Assembler
    https://en.wikipedia.org/wi­ki/Microsoft_Macro_Assembler
  27. IBM Personal Computer (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Personal_Computer
  28. Intel 8251
    https://en.wikipedia.org/wi­ki/Intel_8251
  29. Intel 8253
    https://en.wikipedia.org/wi­ki/Intel_8253
  30. Intel 8255
    https://en.wikipedia.org/wi­ki/Intel_8255
  31. Intel 8257
    https://en.wikipedia.org/wi­ki/Intel_8257
  32. Intel 8259
    https://en.wikipedia.org/wi­ki/Intel_8259
  33. Support/peripheral/other chips – 6800 family
    http://www.cpu-world.com/Support/6800.html
  34. Motorola 6845
    http://en.wikipedia.org/wi­ki/Motorola_6845
  35. The 6845 Cathode Ray Tube Controller (CRTC)
    http://www.tinyvga.com/6845
  36. CRTC operation
    http://www.6502.org/users/an­dre/hwinfo/crtc/crtc.html
  37. 6845 – Motorola CRT Controller
    https://stanislavs.org/hel­ppc/6845.html
  38. The 6845 Cathode Ray Tube Controller (CRTC)
    http://www.tinyvga.com/6845
  39. Motorola 6845 and bitwise graphics
    https://retrocomputing.stac­kexchange.com/questions/10996/mo­torola-6845-and-bitwise-graphics
  40. IBM Monochrome Display Adapter
    http://en.wikipedia.org/wi­ki/Monochrome_Display_Adap­ter
  41. Color Graphics Adapter
    http://en.wikipedia.org/wi­ki/Color_Graphics_Adapter
  42. Color Graphics Adapter and the Brown color in IBM 5153 Color Display
    https://www.aceinnova.com/en/e­lectronics/cga-and-the-brown-color-in-ibm-5153-color-display/
  43. The Modern Retrocomputer: An Arduino Driven 6845 CRT Controller
    https://hackaday.com/2017/05/14/the-modern-retrocomputer-an-arduino-driven-6845-crt-controller/
  44. flat assembler: Assembly language resources
    https://flatassembler.net/
  45. FASM na Wikipedii
    https://en.wikipedia.org/wiki/FASM
  46. Fresh IDE FASM inside
    https://fresh.flatassembler.net/
  47. MS-DOS Version 4.0 Programmer's Reference
    https://www.pcjs.org/docu­ments/books/mspl13/msdos/dos­ref40/
  48. INT 21 – DOS Function Dispatcher (DOS)
    https://www.stanislavs.or­g/helppc/int21.html
  49. DOS API (Wikipedia)
    https://en.wikipedia.org/wiki/DOS_API
  50. IBM Basic assembly language and successors (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Basic_assembly_lan­guage_and_successors
  51. X86 Assembly/Arithmetic
    https://en.wikibooks.org/wi­ki/X86_Assembly/Arithmetic
  52. Art of Assembly – Arithmetic Instructions
    http://oopweb.com/Assembly/Do­cuments/ArtOfAssembly/Volu­me/Chapter6/CH06–2.html
  53. ASM Flags
    http://www.cavestory.org/gu­ides/csasm/guide/asm_flag­s.html
  54. Status Register
    https://en.wikipedia.org/wi­ki/Status_register
  55. Linux assemblers: A comparison of GAS and NASM
    http://www.ibm.com/develo­perworks/library/l-gas-nasm/index.html
  56. Programovani v assembleru na OS Linux
    http://www.cs.vsb.cz/gryga­rek/asm/asmlinux.html
  57. Is it worthwhile to learn x86 assembly language today?
    https://www.quora.com/Is-it-worthwhile-to-learn-x86-assembly-language-today?share=1
  58. Why Learn Assembly Language?
    http://www.codeproject.com/Ar­ticles/89460/Why-Learn-Assembly-Language
  59. Is Assembly still relevant?
    http://programmers.stackex­change.com/questions/95836/is-assembly-still-relevant
  60. Why Learning Assembly Language Is Still a Good Idea
    http://www.onlamp.com/pub/a/on­lamp/2004/05/06/writegreat­code.html
  61. Assembly language today
    http://beust.com/weblog/2004/06/23/as­sembly-language-today/
  62. Assembler: Význam assembleru dnes
    http://www.builder.cz/rubri­ky/assembler/vyznam-assembleru-dnes-155960cz
  63. Programming from the Ground Up Book – Summary
    http://savannah.nongnu.or­g/projects/pgubook/
  64. DOSBox
    https://www.dosbox.com/
  65. The C Programming Language
    https://en.wikipedia.org/wi­ki/The_C_Programming_Langu­age
  66. Hercules Graphics Card (HCG)
    https://en.wikipedia.org/wi­ki/Hercules_Graphics_Card
  67. Complete 8086 instruction set
    https://content.ctcd.edu/cou­rses/cosc2325/m22/docs/emu8086in­s.pdf
  68. Complete 8086 instruction set
    https://yassinebridi.github.io/asm-docs/8086_instruction_set.html
  69. 8088 MPH by Hornet + CRTC + DESiRE (final version)
    https://www.youtube.com/wat­ch?v=hNRO7lno_DM
  70. Area 5150 by CRTC & Hornet (Party Version) / IBM PC+CGA Demo, Hardware Capture
    https://www.youtube.com/wat­ch?v=fWDxdoRTZPc
  71. 80×86 Integer Instruction Set Timings (8088 – Pentium)
    http://aturing.umcs.maine­.edu/~meadow/courses/cos335/80×86-Integer-Instruction-Set-Clocks.pdf
  72. Colour Graphics Adapter: Notes
    https://www.seasip.info/Vin­tagePC/cga.html
  73. Restoring A Vintage CGA Card With Homebrew HASL
    https://hackaday.com/2024/06/12/res­toring-a-vintage-cga-card-with-homebrew-hasl/
  74. Demoing An 8088
    https://hackaday.com/2015/04/10/de­moing-an-8088/
  75. Video Memory Layouts
    http://www.techhelpmanual.com/89-video_memory_layouts.html
  76. Screen Attributes
    http://www.techhelpmanual.com/87-screen_attributes.html
  77. IBM PC Family – BIOS Video Modes
    https://www.minuszerodegre­es.net/video/bios_video_mo­des.htm
  78. EGA Functions
    https://cosmodoc.org/topics/ega-functions/#the-hierarchy-of-the-ega
  79. Why the EGA can only use 16 of its 64 colours in 200-line modes
    https://www.reenigne.org/blog/why-the-ega-can-only-use-16-of-its-64-colours-in-200-line-modes/
  80. How 16 colors saved PC gaming – the story of EGA graphics
    https://www.custompc.com/retro-tech/ega-graphics
  81. List of 16-bit computer color palettes
    https://en.wikipedia.org/wi­ki/List_of16-bit_computer_color_palettes
  82. Why were those colors chosen to be the default palette for 256-color VGA?
    https://retrocomputing.stac­kexchange.com/questions/27994/why-were-those-colors-chosen-to-be-the-default-palette-for-256-color-vga
  83. VGA Color Palettes
    https://www.fountainware.com/EX­PL/vga_color_palettes.htm
  84. Hardware Level VGA and SVGA Video Programming Information Page
    http://www.osdever.net/Fre­eVGA/vga/vga.htm
  85. Hardware Level VGA and SVGA Video Programming Information Page – sequencer
    http://www.osdever.net/Fre­eVGA/vga/seqreg.htm
  86. VGA Basics
    http://www.brackeen.com/vga/ba­sics.html
  87. Introduction to VGA Mode ‚X‘
    https://web.archive.org/web/20160414072210/htt­p://fly.srk.fer.hr/GDM/ar­ticles/vgamodex/vgamx1.html
  88. VGA Mode-X
    https://web.archive.org/web/20070123192523/htt­p://www.gamedev.net/referen­ce/articles/article356.asp
  89. Mode-X: 256-Color VGA Magic
    https://downloads.gamedev­.net/pdf/gpbb/gpbb47.pdf
  90. Instruction Format in 8086 Microprocessor
    https://www.includehelp.com/embedded-system/instruction-format-in-8086-microprocessor.aspx
  91. How to use „AND,“ „OR,“ and „XOR“ modes for VGA Drawing
    https://retrocomputing.stac­kexchange.com/questions/21936/how-to-use-and-or-and-xor-modes-for-vga-drawing
  92. VGA Hardware
    https://wiki.osdev.org/VGA_Hardware
  93. Programmer's Guide to Yamaha YMF 262/OPL3 FM Music Synthesizer
    https://moddingwiki.shika­di.net/wiki/OPL_chip
  94. Does anybody understand how OPL2 percussion mode works?
    https://forum.vcfed.org/in­dex.php?threads/does-anybody-understand-how-opl2-percussion-mode-works.60925/
  95. Yamaha YMF262 OPL3 music – MoonDriver for OPL3 DEMO [Oscilloscope View]
    https://www.youtube.com/watch?v=a7I-QmrkAak
  96. Yamaha OPL vs OPL2 vs OPL3 comparison
    https://www.youtube.com/wat­ch?v=5knetge5Gs0
  97. OPL3 Music Crockett's Theme
    https://www.youtube.com/wat­ch?v=HXS008pkgSQ
  98. Bad Apple (Adlib Tracker – OPL3)
    https://www.youtube.com/wat­ch?v=2lEPH6Y3Luo
  99. FM Synthesis Chips, Codecs and DACs
    https://www.dosdays.co.uk/to­pics/fm_synthesizers.php
ikonka

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.