Hlavní navigace

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

12. 9. 2024
Doba čtení: 49 minut

Sdílet

 Autor: Thomas Nguyen, podle licence: CC BY-SA 4.0
Po popisu grafického subsystému počítačů IBM PC se na chvíli zastavme u instrukční sady mikroprocesorů Intel 8086/8088. Ta je totiž poměrně specifická a navíc i překvapivá v tom, jak dlouho některé instrukce trvají.

Obsah

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

2. Architektura CISC

3. Programátorský model mikroprocesoru Intel 8086

4. Dostupné adresovací režimy

5. Kolik času stojí výpočet adresy operandu?

6. Instrukční sada mikroprocesorů Intel 8088 a Intel 8086

7. Registr s příznaky (FLAGS)

8. Aritmetické instrukce

9. Logické instrukce, bitové posuny a rotace

10. Strojové instrukce určené pro provedení skoku

11. Nepodmíněné skoky

12. Příznaky a podmíněné skoky

13. Vybrané instrukce pro podmíněné skoky založené na testování příznakových bitů

14. Použití instrukcí DEC a JNZ pro implementaci počítané programové smyčky

15. Odlišná realizace počítané smyčky s instrukcemi DEC, JZJMP

16. Počítané programové smyčky realizované instrukcí LOOP

17. Použití instrukce CMP v součinnosti s podmíněným skokem

18. Seznam již popsaných instrukcí

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

20. Odkazy na Internetu

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

Při tvorbě profesionálních aplikací na IBM PC s mikroprocesorem Intel 8088 („ořezaná“ varianta čipu Intel 8086) se většinou používal assembler, protože jen tak bylo možné využít všech dobrých vlastností tohoto čipu (a samozřejmě i obejít ty horší vlastnosti, kterých taktéž bylo mnoho). Tehdejší překladače vyšších programovacích jazyků totiž nedokázaly pro Intel 8086 provádět dobré optimalizace, což bylo způsobeno komplikovanou instrukční sadou, relativně malým množstvím pracovních registrů, využitím jen specifických registrů pro určité operace a pochopitelně taktéž – doposud nepřekonanou – sémantickou mezerou mezi vyššími programovacími jazyky a strojovým kódem (či assemblerem). V dnešním článku a především pak v článku navazujícím se zaměříme právě na popis specifických vlastností instrukční sady Intelu 8086 (a vše platí i pro Intel 8088).

Poznámka: prozatím vynecháme problematiku matematického koprocesoru.

Programátorský model mikroprocesoru Intel 8086 do určité míry vychází z jeho předchůdců, tedy konkrétně z čipů 8080 a 8085. Došlo ovšem k rozšíření sady registrů, k určité unifikaci jejich role (což zjednodušilo instrukční sadu) a k rozšíření pracovních registrů na šířku šestnácti bitů. Navíc se rozšířily adresovací režimy a při adresování se kromě základní 16bitové adresy počítá i adresa segmentu získaná z registrů CS, DS, ES či SS, což umožňuje adresovat 1MB paměti + necelých 64kB nad tímto limitem. Oproti 8080 je zde tedy výrazný skok vpřed, ovšem v porovnání s dalšími mikroprocesory této éry patří 8086 spíše mezi jednodušší mikroprocesory (což ovšem nemusí být vždy špatně).

Mikroprocesory řady Intel 8086 jsou naprosto typickými zástupci CISC architektury, takže se nejprve zmiňme, o co se vlastně jedná. CISC znamená Complex Instruction Set Computer, tj. počítač (ale spíše mikroprocesor) s relativně složitými instrukcemi s vyšší úrovní abstrakce, než instrukce RISC (Reduced Instruction Set Computer).

2. Architektura CISC

CISC je založen na relativně starých myšlenkách. Již v roce 1962 se firma IBM rozhodla navrhnout do značné míry univerzální architekturu počítačů, která by pokrývala jak nároky jednodušších úloh (pro které stačily méně výkonné a tím pádem i levnější počítače), tak i nároky mnohem větší. Předností této architektury mělo být to, že systém „rostl“ současně s rostoucími požadavky zákazníka, a to bez nutnosti měnit programové vybavení (co nám to připomíná?). Výsledkem těchto snah firmy IBM byla platforma nazvaná System/360, resp. zkráceně S/360. Pro tuto platformu byla vytvořena poměrně rozsáhlá a složitá instrukční sada (ISA), která mimo běžné binární aritmetiky obsahovala i instrukce pro práci s textem, různé numerické formáty dat známé například z kalkulaček, ale i podporu BCD aritmetiky, která se dodnes používá například při výpočtech s měnou. V té době totiž vládlo přesvědčení, že bohatší instrukční sada ulehčí práci překladačům z vyšších programovacích jazyků, vyplní takzvanou sémantickou mezeru mezi assemblerem a vyššími programovacími jazyky atd.

Vzhledem ke složitosti instrukční sady System/360 se v praxi používaly mikroprogramy, tj. jednodušší procesory s touto architekturou kompatibilní mnoho instrukcí přímo nevykonávaly, ale vlastně emulovaly na základě takzvaného mikrokódu (mikroinstrukcí uložených v mikrořadiči) – jednalo se tedy o obdobu dnes populárních bytekódů, které také mohou být emulovány přímo v mikroprocesorech (mikroprogramem), nikoli uživatelským programem. Teprve mnohem později byly podobně koncipované instrukční sady a mikroprocesory nazvány CISC neboli Complex Instruction Set Code (v některých případech byly i mikroinstrukce pro přímé vykonání zbytečně složité, a proto byly rozkládány do takzvaných nanoinstrukcí, což vedlo ke snížení potřebné kapacity paměti v mikrořadiči i zjednodušení návrhu samotného mikroprocesoru).

Procesory s architekturou CISC se většinou vyznačují velmi obsáhlou instrukční sadou, mnohdy do značné míry ortogonální (tj. většina instrukcí může být použita se všemi adresními režimy). To ovšem vede k nutnosti použití složitého řadiče, instrukce trvají i několik desítek či stovek taktů a celková složitost mikroprocesoru obecně roste. Před cca 10–15 lety se zdálo, že celá architektura CISC bude opuštěna a nahrazena architekturou RISC. Ve skutečnosti však vznikly jakési hybridní architektury – dnes nejpopulárnější mikroprocesory jsou sice interně vytvořeny jako RISCové, ale jejich instrukční sada je CISCová. V této kombinaci se ukazují výhody obou architektur: velká rychlost a interní jednoduchost RISCů a současně kratší kód instrukcí u CISC procesorů (snižují se nároky na vyrovnávací paměti). Pro příklad nemusíme chodit daleko, protože do tohoto stavu došla i platforma x86 (a před ní VAX či Motorola 68060). I populární 32bitové RISCové procesory ARM obsahují instrukční sadu nazvanou Thumb, která umožňuje snížení velikosti programů o cca 30–40 %.

Pro ilustraci „komplexnosti“ instrukční sady následuje příklad části programu napsaného v assembleru CISCové architektury x86. Všimněte si různých adresních režimů, implicitně zadaných operandů u instrukce imul, segmentového adresování pomocí segmentového registru es, i toho, že u aritmetických instrukcí je možné používat operandy přímo načítané z operační paměti (mov es, ax, add ax,[zy1]), což je pro CISCové architektury typické a naopak netypické pro architekturu RISC:

mov     ax,bp
sar     ax,cl
imul    ax          ; implicitní operandy: dx:ax=ax*ax
push    ax
 
mov     ax,bx
sar     ax,cl       ; při bitovém posunu se musí použít registr cl
imul    ax
mov     es:[di],ax  ; uložení obsahu registru do paměti
 
mov     ax,bp
sar     ax,cl
sar     bx,5
imul    bx          ; implicitní operandy: dx:ax=ax*bx
add     ax,[zy1]    ; jeden z operandů je načten z operační paměti
xchg    ax,bx
 
pop     ax
push    ax
sub     ax,es:[di]
add     ax,[zx1]
mov     bp, ax
pop     ax
add     ax,es:[di]
dec     ch
jz      short pokrac
cmp     ax,4*P
jc      short opak
stosb               ; další instrukce s implicitními operandy (porušení ortogonality)
Poznámka: v některých případech se i díky CISC podařila konstruktérům procesorů vytvořit instrukční sada s velmi „hustým“ instrukčním kódem, kdy se využívaly instrukce s proměnnou délkou. Týkalo se to především použití sofistikovanějších adresních režimů, například při současném použití bázového registru, indexového registru násobeného konstantou a offsetu (příkladem může být instrukční sada procesorů řady i386, v níž je možné adresovací režimy využít i pro relativně složité výpočty prováděné například instrukcí LEA – Load Effective Address). K této problematice se pochopitelně ještě vrátíme.

3. Programátorský model mikroprocesoru Intel 8086

Nejprve si vysvětlíme takzvaný programátorský model mikroprocesorů řady Intel 8086, tedy i včetně čipu Intel 8088 použitého v první generaci IBM PC. Stručně řečeno popisuje programátorský model dostupné registry, adresovací režimy a skupinu použitelných instrukcí. Začněme s popisem registrů. Celkově je možné pracovat s těmito čtrnácti registry, které mají všechny šířku šestnácti bitů (u dalších modelů x86 to už tak jednoduché ani zdaleka nebude, protože některé registry jsou rozšířeny na 32bitů atd.):

# Typ registrů Počet registrů Bitová šířka registru Názvy registrů
1 Univerzální registry 4 16 bitů AX, BX, CX, DX
2 Indexové registry 2 16 bitů SI, DI
3 Bázové registry 2 16 bitů BP, SP (ale logicky sem spadá i BX)
4 Segmentové registry 4 16 bitů CS, DS, ES, SS
5 Příznakový registr 1 16 bitů FLAGS
6 Programový čítač 1 16 bitů IP

První čtyři registry jsou sice nazvány univerzální, ovšem jejich role není zcela zaměnitelná. Každý z těchto registrů má totiž kromě své základní role ještě další roli/role a vystupuje jako implicitní operand u mnoha specifických instrukcí (instrukční sada není v žádném případě ortogonální, naopak se jedná o snad nejméně ortogonální sadu v oblasti 16bitových čipů). Navíc se tyto registry rozdělují na „horní“ a „dolní“ osmibitové registry (tj. změna AL modifikuje spodních osm bitů registru AX a naopak):

Registr Rozdělení Význam
AX AH/AL akumulátor
BX BH/BL bázová adresa
CX CH/CL čítač (counter)
DX DH/DL data, rozšíření akumulátoru pro 32bitové operace atd.
Poznámka: jak uvidíme dále, tak pro mnoho instrukcí existuje kratší operační kód v případě, že se jako první (nebo jediný) operand využije akumulátor. Stále je zde patrný odkaz na dobu mikroprocesorů 8008 a 8080.

Jména registrů SI a DI vznikla ze sousloví Source Index a Destination Index a jméno registru BP znamená Base Pointer.

4. Dostupné adresovací režimy

U procesorů Intel 8086/8088 je dostupných hned několik adresovacích režimů, které jsou dokonce pojmenovány (i když v praxi se většinou toto pojmenování nepoužívá). Podívejme se nyní, které režimy jsou podporovány:

Název režimu Stručný popis Ukázka instrukce
register operandem je přímo zapsaný registr add AX, BX
immediate operandem je konstanta (8bit, 16bit) mov AL, 3; mov BX, 42
displacement/direct operandem je přímá adresa inc byte [123], inc word [123]
register indirect operandem je adresa uložená v SI, DI nebo BX mov AX, [DI]
based indexed mode operandem je bázová adresa (BX, BP) zvýšená o offset (SI, DI) mov AX, [BX+DI]
indexed mode operandem je bázová adresa (SI, DI) zvýšená o offset (konstanta) mov AX, [SI+1000]
based mode dtto, ale pro bázový registr a offset mov AX, [BP+1000]
based indexed displacement adresa je vypočtena z indexového registru, bázového registru a offsetu mov AX, [SI+BP+offset]
string pro adresování se implicitně použije ES:DI nebo DS:SI movs, stosb, loadsw

Všechny možné kombinace zápisu adres (tedy ne přímo konstant či registrů v roli operandů) jsou vypsány v následující tabulce. Více kombinací už pro 8086/8088 neexistuje (vynecháno je adresování řetězců, to je totiž implicitní):

Použitý zápis v assembleru Adresovací režim
přímá adresa (16bit) displacement/direct
   
[BX] register indirect
[SI] register indirect
[DI] register indirect
   
[BX+SI] based indexed mode
[BX+DI] based indexed mode
[BP+SI] based indexed mode
[BP+DI] based indexed mode
   
[BP+offset8_bit] based mode
[BX+offset8_bit] based mode
[SI+offset8_bit] indexed mode
[DI+offset8_bit] indexed mode
   
[BP+offset16_bit] based mode
[BX+offset16_bit] based mode
[SI+offset16_bit] indexed mode
[DI+offset16_bit] indexed mode
   
[BX+SI+offset8_bit] based indexed displacement
[BX+DI+offset8_bit] based indexed displacement
[BP+SI+offset8_bit] based indexed displacement
[BP+DI+offset8_bit] based indexed displacement
   
[BX+SI+offset16_bit] based indexed displacement
[BX+DI+offset16_bit] based indexed displacement
[BP+SI+offset16_bit] based indexed displacement
[BP+DI+offset16_bit] based indexed displacement
Poznámka: chybějící adresovací režim [BP] je assemblery nahrazen za variantu [BP+0], která je o bajt delší.

Příklad využití některých výše uvedených adresovacích režimů v naprosto umělém příkladu:

;-----------------------------------------------------------------------------
 
BITS 16         ; 16bitovy vystup pro DOS
CPU 8086        ; specifikace pouziteho instrukcniho souboru
 
;-----------------------------------------------------------------------------
org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        add ax, bx
        mov ax, [bx]
        mov ax, [si]
        mov ax, [di]
        mov ax, [bp]
 
        mov ax, [bx+0x1f]
        mov ax, [si+0x1f]
        mov ax, [di+0x1f]
        mov ax, [bp+0x1f]
 
        mov ax, [bx+0xeeff]
        mov ax, [si+0xeeff]
        mov ax, [di+0xeeff]
        mov ax, [bp+0xeeff]
 
        mov ax, [bp+si]
        mov ax, [bp+di]
        mov ax, [bp+si+0x1f]
        mov ax, [bp+di+0xeeff]
        mov al, 42
        mov ax, 42
        inc byte [123]
        inc word [123]
        inc byte [10000]
        inc word [10000]

Překlad do strojového kódu vypadá následovně (povšimněte si délky jednotlivých instrukcí) a například rozdílu mezi [di] a [bp]:

     1                                  ;-----------------------------------------------------------------------------
     2
     3                                  BITS 16         ; 16bitovy vystup pro DOS
     4                                  CPU 8086        ; specifikace pouziteho instrukcniho souboru
     5
     6                                  ;-----------------------------------------------------------------------------
     7                                  org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
     8
     9                                  start:
    10 00000000 01D8                            add ax, bx
    11 00000002 8B07                            mov ax, [bx]
    12 00000004 8B04                            mov ax, [si]
    13 00000006 8B05                            mov ax, [di]
    14 00000008 8B4600                          mov ax, [bp]
    15
    16 0000000B 8B471F                          mov ax, [bx+0x1f]
    17 0000000E 8B441F                          mov ax, [si+0x1f]
    18 00000011 8B451F                          mov ax, [di+0x1f]
    19 00000014 8B461F                          mov ax, [bp+0x1f]
    20
    21 00000017 8B87FFEE                        mov ax, [bx+0xeeff]
    22 0000001B 8B84FFEE                        mov ax, [si+0xeeff]
    23 0000001F 8B85FFEE                        mov ax, [di+0xeeff]
    24 00000023 8B86FFEE                        mov ax, [bp+0xeeff]
    25
    26 00000027 8B02                            mov ax, [bp+si]
    27 00000029 8B03                            mov ax, [bp+di]
    28 0000002B 8B421F                          mov ax, [bp+si+0x1f]
    29 0000002E 8B83FFEE                        mov ax, [bp+di+0xeeff]
    30 00000032 B02A                            mov al, 42
    31 00000034 B82A00                          mov ax, 42
    32 00000037 FE067B00                        inc byte [123]
    33 0000003B FF067B00                        inc word [123]
    34 0000003F FE061027                        inc byte [10000]
    35 00000043 FF061027                        inc word [10000]
Poznámka: povšimněte si taktéž, že přímá adresa je vždy 16bitová.

5. Kolik času stojí výpočet adresy operandu?

Mikroprocesory Intel 8086 jsou, na rozdíl od jejich následovníků, zvláštní v tom, že výpočet takzvané efektivní adresy (tj. adresy operandu) je velmi zdlouhavý a závisí na použitém adresovacím režimu. Je to mj. i z toho důvodu, že výpočet efektivní adresy využívá ALU a nikoli specializovanou sčítačku.

Podívejme se na typickou zdánlivě „krátkou“ instrukci, konkrétně na instrukci ADD. Doba jejího vykonání nezávisí na šířce operandů (8 nebo 16 bitů), ale na adresovacím režimu:

Operandy Počet cyklů
reg, reg 3
mem, reg 24+EA
reg, mem 13+EA
reg, imm 4
mem, imm 23+EA
acc, imm 4

Hodnota EA závisí na adresovacím režimu:

Adresování Počet cyklů EA
reg+offset 5
přímá adresa 6
BP+DI nebo BX+SI 7
BX+DI nebo BP+SI 8
BP+DI+disp nebo BX+SI+disp 11
BX+DI+disp nebo BP+SI+disp 12

Navíc, pokud se mění (explicitně specifikuje) segmentový registr, je nutné přičíst další dva hodinové cykly.

To například znamená, že instrukce:

add CS:[BX+DI+1234], AX

bude trvat 24+12=36 cyklů (tedy evidentně se skutečně nejedná o RISC přístup).

Poznámka: na druhou stranu to umožnilo společnosti Intel provádět postupné optimalizace, zde konkrétně na 10 cyklů na 80186, 7 cyklů na 80286 a 3 cykly na 80486 i Pentiu. Navíc to znamená, že nemá smysl porovnávat tyto čipy jen na základě hodinové frekvence; ten údaj je spíše méně významný, když 8086 a 80486 na (teoreticky) stejné hodinové frekvenci vykonají totožnou instrukci v 36 cyklech resp. ve třech cyklech.

6. Instrukční sada mikroprocesorů Intel 8088 a Intel 8086

Poměrně rozsáhlá sada instrukcí mikroprocesorů Intel 8088 a Intel 8086 je vypsána v následující tabulce. K jednotlivým instrukcím se ještě vrátíme při jejich podrobnějším popisu:

AAA ASCII adjust AL after addition
AAD ASCII adjust AX before division
AAM ASCII adjust AX after multiplication
AAS ASCII adjust AL after subtraction
ADC Add with carry
ADD Add
AND Logical AND
CALL Call procedure
CBW Convert byte to word
CLC Clear carry flag
CLD Clear direction flag
CLI Clear interrupt flag
CMC Complement carry flag
CMP Compare operands
CMPSB Compare bytes in memory
CMPSW Compare words
CWD Convert word to doubleword
DAA Decimal adjust AL after addition
DAS Decimal adjust AL after subtraction
DEC Decrement by 1
DIV Unsigned divide
ESC Used with floating-point unit
HLT Enter halt state
IDIV Signed divide
IMUL Signed multiply in One-operand form
IN Input from port
INC Increment by 1
INT Call to interrupt
INTO Call to interrupt if overflow
IRET Return from interrupt
Jcc Jump if condition
JCXZ Jump if CX is zero
JMP Jump
LAHF Load FLAGS into AH register
LDS Load DS:r with far pointer
LEA Load Effective Address
LES Load ES:r with far pointer
LOCK Assert BUS LOCK# signal
LODSB Load string byte
LODSW Load string word
LOOP/LOOPx Loop control
MOV Move
MOVSB Move byte from string to string
MOVSW Move word from string to string
MUL Unsigned multiply
NEG Two's complement negation
NOP No operation
NOT Negate the operand, logical NOT
OR Logical OR
OUT Output to port
POP Pop data from stack
POPF Pop FLAGS register from stack
PUSH Push data onto stack
PUSHF Push FLAGS onto stack
RCL Rotate left (with carry)
RCR Rotate right (with carry)
REPxx Repeat MOVS/STOS/CMPS/LODS/SCAS
RET Return from procedure
RETN Return from near procedure
RETF Return from far procedure
ROL Rotate left
ROR Rotate right
SAHF Store AH into FLAGS
SAL Shift Arithmetically left (signed shift left)
SAR Shift Arithmetically right (signed shift right)
SBB Subtraction with borrow
SCASB Compare byte string
SCASW Compare word string
SHL Shift left (unsigned shift left)
SHR Shift right (unsigned shift right)
STC Set carry flag
STD Set direction flag
STI Set interrupt flag
STOSB Store byte in string
STOSW Store word in string
SUB Subtraction
TEST Logical compare (AND)
WAIT Wait until not busy
XCHG Exchange data
XLAT Table look-up translation
XOR Exclusive OR

7. Registr s příznaky (FLAGS)

Na platformě Intel 8086 se používá, ostatně podobně jako na většině ostatních platforem (kromě MIPS), takzvaný příznakový registr nazvaný FLAGS. Stejně jako všechny ostatní registry je i FLAGS šestnáctibitový (na 386 byl rozšířen na 32 bitů, později ani tato šířka nestačila, tak vznikly další registry). Příznakový registr obsahuje skutečné příznaky výsledků operací (například nulovost), ale i bity, které řídí chování některých instrukcí (například způsob průchodu řetězcem atd.). Význam jednotlivých bitů příznakového registru je následující:

Bit Příznak Stručný popis příznaku
0 CF příznak přenosu (carry)
1 × rezervováno
2 PF příznak (bitové) parity
3 × rezervováno
4 AF příznak přenosu ze třetího do čtvrtého bitu (auxiliary carry)
5 × rezervováno
6 ZF příznak nulovosti (zero)
7 SF příznak znaménka (sign)
8 TF příznak nastavený při krokování
9 IF povolení či zákaz reakce na přerušení
10 DF směr změny adres při blokových (řetězcových) operacích
11 OF příznak přetečení (overflow)
12 × na 8086 rezervováno, použito až v 286
13 × na 8086 rezervováno, použito až v 286
14 × na 8086 rezervováno, použito až v 286
15 × na 8086 rezervováno, použito až v 286
Poznámka: povolení a zákaz přerušení se provádí instrukcemi STI (Set Interrupt Flag – enable) a CLI (Clear Interrupt Flag – disable).

8. Aritmetické instrukce

První skupinou instrukcí, se kterou se v dnešním článku seznámíme, jsou aritmetické instrukce. Na platformě Intel 8086 nalezneme všechny základní aritmetické instrukce, a to včetně násobení a dělení se znaménkem i bez znaménka. Tyto instrukce jsou však relativně pomalé. Počty cyklů nutných pro dokončení jednotlivých operací jsou naznačeny v tabulce (pro ten nejrychlejší způsob, tedy pro operace typu registr+registr):

Instrukce Cyklů Stručný popis instrukce
ADD 3 součet
ADC 3 součet se započtením předchozího přenosu (carry)
SUB 3 rozdíl
SBB 3 rozdíl se započtením předchozí výpůjčky (borrow)
     
CMP 3 porovnání s nastavením příznaků
     
INC 3 zvýšení operandu o jedničku
DEC 3 snížení operandu o jedničku
     
MUL 70–77 (8bit), 118–133 (16bit) násobení bez znaménka, výsledek v AX nebo DX:AX
DIV 80–90 (8bit), 144–162 (16bit) dělení a výpočet zbytku po dělení bez znaménka
IMUL 80–98 (8bit), 128–154 (16bit) násobení se znaménkem
IDIV 101–112 (8bit), 165–184 (16bit) dělení se znaménkem
     
NEG 3 negace (otočení znaménka)
Poznámka: kvůli pomalosti operací pro násobení a dělení se vyplatí (resp. vyplatilo) investovat čas do tvorby optimalizovaných algoritmů založených na logických posunech.

Kvůli dlouhým časům násobení není divu, že se pro zpracování signálu používaly specializované DSP s velmi rychlou násobičkou.

9. Logické instrukce, bitové posuny a rotace

Mikroprocesor Intel 8086 pochopitelně obsahuje prakticky úplnou sadu logických instrukcí a instrukcí určených pro provedení bitových posunů a rotací. U instrukcí posunů a rotací je zajímavé, že operace posunu/rotace o jeden bit je velmi rychlá, ale posun o CL bitů naopak velmi pomalá, takže se (většinou) na Intel 8086 vyplatí si rozepsat například násobení osmi na tři posuny a nikoli na posun o tři bity:

Instrukce Cyklů Stručný popis instrukce
AND 3 bitová operace logického součinu
OR 3 bitová operace logického součtu
XOR 3 bitová operace nonekvivalence
     
NOT 3 negace všech bitů
     
TEST 3 provedení logického součinu bez uložení výsledku (mění se jen příznaky)
     
RCL 2 (rotace o bit) nebo 8+4n rotace (9 nebo 17 bitů) přes příznak CF doleva
RCR 2 (rotace o bit) nebo 8+4n rotace (9 nebo 17 bitů) přes příznak CF doprava
ROL 2 (rotace o bit) nebo 8+4n rotace osmi či šestnácti bitů doleva
ROR 2 (rotace o bit) nebo 8+4n rotace osmi či šestnácti bitů doprava
     
SAL 2 (posun o bit) nebo 8+4n aritmetický posun doleva (stejné jako SHL)
SHL 2 (posun o bit) nebo 8+4n bitový posun doleva (stejné jako SAL)
SAR 2 (posun o bit) nebo 8+4n aritmetický posun doprava (zleva se nasunuje příznak SF)
SHR 2 (posun o bit) nebo 8+4n bitový posun doprava (zleva se nasunuje nula)
Poznámka: u aritmetických i bitových posunů se bit, který se z registru „ztrácí“, přesouvá do příznaku CF. U rotací přes CF je rotace provedeno pro devět bitů a pro ROR/ROL se bit, který rotuje, kopíruje do CF.

10. Strojové instrukce určené pro provedení skoku

Velmi důležitým typem strojových instrukcí, které v různé podobě najdeme prakticky u všech modelů mikroprocesorů (resp. přesněji řečeno u mikroprocesorů všech dnes rozšířených mikroprocesorových architektur), jsou instrukce provádějící skoky na nějakou adresu v operační paměti. Implementace skoku není, alespoň na první pohled a u jednodušších architektur bez instrukční pipeline, vlastně nijak složitá, protože se v případě použití absolutní adresy dosadí hodnota z operačního kódu instrukce do registru IP a v případě použití relativní adresy se tato hodnota (nazývaná někdy poněkud nepřesně offset) přičte k aktuální hodnotě registru PC. Relativní adresa je v tomto případě v kódu instrukce uložena se znaménkem, proto se skok může provést dozadu i dopředu (ostatně právě použití relativní adresy uvidíme v dále popisovaných demonstračních příkladech).

Skoky většinou dělíme podle jednoho kritéria (formy zápisu adresy) na absolutní a relativní a podle kritéria druhého (za jakým okolností se skok provede) na skoky podmíněné a nepodmíněné. V závislosti na použité instrukční sadě jsou možné různé kombinace, typicky však u většiny mikroprocesorů nalezneme kombinace nepodmíněný absolutní skok, nepodmíněný relativní skok a podmíněný relativní skok. Skoky nepodmíněné jsou jednodušší a svou podstatou odpovídají příkazu goto známého z některých programovacích jazyků a také z mnoha článků, ve kterých autoři mnohdy bez hlubšího zamyšlení se nad původní myšlenkou opakují, že by se goto nemělo při strukturovaném programování používat :-). V assembleru se však skoky vesele používají, neboť právě pomocí nich se vytváří základní konstrukce strukturovaného programování – podmínky a programové smyčky (navíc relativní a tudíž i lokální skok není ta nejhorší možná abstrakce).

11. Nepodmíněné skoky

U architektury mikroprocesorů Intel 8086 je základní strojovou instrukcí určenou pro provedení nepodmíněného skoku instrukce nazvaná jednoduše a přímočaře JMP (což je, jak jste zajisté zjistili, mnemotechnická zkratka slova jump). V assembleru většinou za mnemotechnickou zkratkou jména instrukce následuje návěští (label), z něhož assembler odvodí reálnou adresu. Ukažme si typický špagetový kód vznikající nadbytečným použitím této instrukce:

org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        jmp     cil1
 
zpet:
        ; tisk retezce na obrazovku
        mov     dx, message
        mov     ah, 9
        int     0x21
 
        ; ukonceni procesu a navrat do DOSu
        mov     ah, 0x4c
        int     0x21
 
cil2:   jmp cil3
cil1:   jmp cil2
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db "Hello, world!", 0x0d, 0x0a, "$"
 
cil3:   jmp zpet

Podívejme se, jak se vlastně instrukce JMP přeloží – kolik má bajtů, zda obsahuje relativní nebo absolutní adresu atd.:

     1
     2                                  org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
     3
     4                                  start:
     5 00000000 EB0D                            jmp     cil1
     6
     7                                  zpet:
     8                                          ; tisk retezce na obrazovku
     9 00000002 BA[1100]                        mov     dx, message
    10 00000005 B409                            mov     ah, 9
    11 00000007 CD21                            int     0x21
    12
    13                                          ; ukonceni procesu a navrat do DOSu
    14 00000009 B44C                            mov     ah, 0x4c
    15 0000000B CD21                            int     0x21
    16
    17 0000000D EB12                    cil2:   jmp cil3
    18 0000000F EBFC                    cil1:   jmp cil2
    19
    20                                          ; retezec ukonceny znakem $
    21                                          ; (tato data jsou soucasti vysledneho souboru typu COM)
    22 00000011 48656C6C6F2C20776F-     message db "Hello, world!", 0x0d, 0x0a, "$"
    22 0000001A 726C64210D0A24
    23
    24 00000021 EBDF                    cil3:   jmp zpet
Poznámka: zde konkrétně se používá takzvaná short varianta skoku s osmibitovou relativní adresou – celá instrukce tak má délku 2 bajty.

12. Příznaky a podmíněné skoky

Alternativně je možné použít i další způsoby adresování, čímž se například implementuje tabulka skoků (jedna z možných realizací stavového automatu) atd., ovšem tyto techniky pro účely dnešního článku prozatím nepotřebujeme znát. Mnohem zajímavější jsou podmíněné skoky, které se při programování v assembleru či ve strojovém kódu používají pro implementaci programových smyček while, do-while, for a taktéž konstrukcí typu if-then-else atd. Podmíněný skok je proveden či naopak neproveden na základě nějaké podmínky. Vzhledem k tomu, že pracujeme na té nejnižší programové úrovni, tj. na úrovni strojových instrukcí, není samozřejmě možné podmínku definovat nějakým složitým a sofistikovaným způsobem – musí se jednat o operaci, kterou mikroprocesor dokáže jednoduše a především dostatečně rychle zpracovat (i přesto představují skoky úzké místo v programech).

Z tohoto prostého důvodu – podmínky musí být realizovány dostatečně jednoduchým způsobem pro snadnou implementaci na čipu – jsou na mikroprocesorových architekturách Intel 8086 podmínky založeny na testování jednoho z takzvaných příznakových bitů, negací těchto bitů či dokonce jejich kombinací. Pokud z důvodu zjednodušení výkladu celé relativně rozsáhlé problematiky budeme ignorovat některé speciálnější příznaky a především pak rozdíly mezi hodnotami bez znaménka (unsigned) a se znaménkem (signed), můžeme zpočátku použít především příznaky nazvané Carry flag, Sign flag a Zero flag, tj. příznak přenosu, příznak záporného výsledku a příznak nulovosti. Význam těchto příznakových bitů je shrnut v následující tabulce:

Příznak Význam zkratky Poznámka
ZF zero flag výsledek předchozí operace je nulový
CF carry flag přenos (bezznaménková aritmetika)
SF sign flag výsledek je záporný (nastaven nejvyšší bit bajtu či slova)

V případě, že alespoň prozatím nebudeme brát v úvahu další příznakové bity, existuje šest základních variant podmíněného skoku, které jsou vypsány v tabulce v navazující kapitole. Ve chvíli, kdy podmínka není splněna (tj. testovaný příznakový bit má opačnou hodnotu než očekávanou), není skok proveden, tj. mikroprocesor instrukci skoku v podstatě ignoruje a pokračuje v načtení instrukce uvedené ihned za skokem (to, že mikroprocesor instrukci skoku ignoruje samozřejmě platí jen z pohledu logiky vytvářeného programu; samotné provedení instrukce muselo proběhnout a tudíž se program o několik strojových taktů pozdržel – i neprovedení podmíněného kroku si tedy vyžádalo svou cenu).

13. Vybrané instrukce pro podmíněné skoky založené na testování příznakových bitů

Strojové instrukce určené pro provedení podmíněných skoků jsou ve své základní variantě (existují pro ně totiž i jmenné aliasy) pojmenovány jednoduše a přímočaře – jejich jména začínají znakem J (jump), za nímž následuje volitelné písmeno N (negace) a jednoznaková zkratka příznaku. Instrukce JNC tedy znamená „proveď skok, pokud příznak Carry není nastaven“, zatímco instrukce JZ znamená „proveď skok pouze při nastavení příznaku Zero“:

Mnemotechnická zkratka instrukce Význam instrukce podmíněného skoku
JC podmíněný skok za předpokladu, že je nastaven příznak přenosu (Carry flag)
JNC podmíněný skok za předpokladu, že je vynulován příznak přenosu (Carry flag)
JZ podmíněný skok za předpokladu, že je nastaven příznak nulovosti (Zero flag)
JNZ podmíněný skok za předpokladu, že je vynulován příznak nulovosti (Zero flag)
JS podmíněný skok za předpokladu, že je nastaven příznak záporného výsledku (Sign flag)
JNS podmíněný skok za předpokladu, že je vynulován příznak záporného výsledku (Sign flag)

Jmenné aliasy:

Instrukce Alias
JZ JE
JNZ JNE
JC JB, JNAE
JNC JNB, JAE
JS nemá alias
JNS nemá alias

14. Použití instrukcí DEC a JNZ pro implementaci počítané programové smyčky

V předchozí kapitole jsme si řekli, že podmíněné relativní skoky jsou použity pro implementaci programových smyček a podmínek. K tomuto účelu se podmíněné skoky prakticky vždy vhodně kombinují s některou instrukcí, která modifikuje jeden příznakový bit či dokonce větší množství příznakových bitů. Například jednoduchou počítanou programovou smyčku by bylo možné implementovat s využitím kombinace strojových instrukcí DEC a JNZ. Instrukce nazvaná DEC snižuje obsah specifikovaného pracovního registru o jedničku a současně nastavuje příznak nuly, tj. Zero flag (ZF), samozřejmě ovšem pouze za předpokladu, že ten pracovní registr, jehož hodnota se snižuje, skutečně dosáhl nulové hodnoty. Instrukce JNZ znamená podmíněný skok, který je proveden pouze tehdy, pokud příznak nuly není nastaven („jump if not zero“, viz též předchozí kapitolu).

Před samotným začátkem programové smyčky je samozřejmě nutné do pracovního registru nastavit potřebný počet opakování, který by měl být ideálně odlišný od nuly. Ostatně zkuste si sami odpovědět na otázku, co by se stalo v případě, kdy by pracovní registr použitý jako počitadlo, byl před vstupem do smyčky vynulovaný. Podívejme se nyní na způsob použití 16bitového registru AX (akumulátory) ve funkci počitadla. Vzhledem k tomu, že se testuje pouze nulovost registru po snížení jeho hodnoty o jedničku, může tato smyčka být provedena 0× až 216-1× (ignoruje se znaménko):

        MOV AX, počet_opakování ; počet opakování smyčky
SMYCKA: příkaz 1                 ; libovolné instrukce, jejichž celková
        příkaz 2                 ; celková délka bloku musí být menší než cca 120 bytů
        ...                      ; (kvůli omezení relativního skoku, pokud se délka překročí, použije se delší instrukce)
        ...
        ...
        příkaz X
        DEC EAX                  ; snížení čítače smyčky o jedničku
        JNZ SMYCKA               ; přeloží se jako relativní skok

Praktický příklad – výpis zprávy 10×, jako počitadlo je použit registr CX:

org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        mov     cx, 10       ; pocatecni hodnota pocitadla
opak:
        ; tisk retezce na obrazovku
        mov     dx, message
        mov     ah, 9
        int     0x21
 
        dec     cx            ; snizeni pocitadla o jednicku
        jnz     opak          ; skok, dokud se nedosahne nuly
 
        ; ukonceni procesu a navrat do DOSu
        mov     ah, 0x4c
        int     0x21
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db "Hello, world!", 0x0d, 0x0a, "$"

Překlad do strojového kódu ukazuje, že se opět používá short varianta relativního skoku:

     1
     2                                  org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
     3
     4                                  start:
     5 00000000 B90A00                          mov     cx, 10       ; pocatecni hodnota pocitadla
     6                                  opak:
     7                                          ; tisk retezce na obrazovku
     8 00000003 BA[1100]                        mov     dx, message
     9 00000006 B409                            mov     ah, 9
    10 00000008 CD21                            int     0x21
    11
    12 0000000A 49                              dec     cx            ; snizeni pocitadla o jednicku
    13 0000000B 75F6                            jnz     opak          ; skok, dokud se nedosahne nuly
    14
    15                                          ; ukonceni procesu a navrat do DOSu
    16 0000000D B44C                            mov     ah, 0x4c
    17 0000000F CD21                            int     0x21
    18
    19                                          ; retezec ukonceny znakem $
    20                                          ; (tato data jsou soucasti vysledneho souboru typu COM)
    21 00000011 48656C6C6F2C20776F-     message db "Hello, world!", 0x0d, 0x0a, "$"
    21 0000001A 726C64210D0A24

15. Odlišná realizace počítané smyčky s instrukcemi DEC, JZJMP

Podmínku ovšem můžeme naopak přesunout i na samotný začátek smyčky. Nyní se ovšem namísto instrukce pro podmíněný skok JNZ použije instrukce JZ (tedy opačná podmínka) v kombinaci s instrukcí nepodmíněného skoku JMP:

        MOV AX, počet_opakování  ; počet opakování smyčky
SMYCKA: DEC AX                   ; snížení čítače smyčky o jedničku
        JZ  KONEC                ; přeloží se jako relativní skok
        příkaz 1                 ; libovolné instrukce, jejichž celková
        příkaz 2                 ; celková délka bloku musí být menší než cca 120 bytů
        ...                      ; (kvůli omezení relativního skoku, pokud se délka překročí, použije se delší instrukce)
        ...
        ...
        příkaz X
        JMP SMYCKA               ; nepodmíněný skok na začátek smyčky

Opět si to ukažme v praxi na realizaci výpisu zprávy několikrát na obrazovku:

org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        mov     cx, 10       ; pocatecni hodnota pocitadla
opak:
        ; tisk retezce na obrazovku
        mov     dx, message
        mov     ah, 9
        int     0x21
 
        dec     cx            ; snizeni pocitadla o jednicku
        jz      konec         ; skok, pokus se dosahne nuly
 
        jmp     opak          ; opakujeme smycku
konec:
        ; ukonceni procesu a navrat do DOSu
        mov     ah, 0x4c
        int     0x21
 
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db "Hello, world!", 0x0d, 0x0a, "$"

Opět si pro úplnost ukažme překlad do strojového kódu:

     1
     2                                  org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
     3
     4                                  start:
     5 00000000 B90A00                          mov     cx, 10       ; pocatecni hodnota pocitadla
     6                                  opak:
     7                                          ; tisk retezce na obrazovku
     8 00000003 BA[1300]                        mov     dx, message
     9 00000006 B409                            mov     ah, 9
    10 00000008 CD21                            int     0x21
    11
    12 0000000A 49                              dec     cx            ; snizeni pocitadla o jednicku
    13 0000000B 7402                            jz      konec         ; skok, pokus se dosahne nuly
    14
    15 0000000D EBF4                            jmp     opak          ; opakujeme smycku
    16                                  konec:
    17                                          ; ukonceni procesu a navrat do DOSu
    18 0000000F B44C                            mov     ah, 0x4c
    19 00000011 CD21                            int     0x21
    20
    21
    22                                          ; retezec ukonceny znakem $
    23                                          ; (tato data jsou soucasti vysledneho souboru typu COM)
    24 00000013 48656C6C6F2C20776F-     message db "Hello, world!", 0x0d, 0x0a, "$"
    24 0000001C 726C64210D0A24

16. Počítané programové smyčky realizované instrukcí LOOP

V předchozích dvou demonstračních příkladech jsme použili pracovní registr CX v roli počitadla programové smyčky. Zápis této smyčky vypadal zhruba následovně:

smyčka:
        ...
        ...
        ...
        dec cx            ; snizeni hodnoty CL
        jnz smyčka        ; skok pri nenulovosti vysledku

Ve skutečnosti je možné tyto dvě instrukce nahradit za jedinou instrukci LOOP, která provádí totožnou operaci, tj. snížení hodnoty CX následované skokem ve chvíli, kdy CX ještě nedosáhla nuly:

smyčka:
        ...
        ...
        ...
        loop smyčka    ; snizeni hodnoty CX, skok pri nenulovosti vysledku

Jak je tato smyčka výhodná nám ukáže následující tabulka:

Operace Bajtů Cyklů
DEC+JNZ 1+2 3+4 nebo 3+16
LOOP 2 5 nebo 17

První varianta je tedy pomalejší a současně i delší, než varianta s instrukcí LOOP.

Zkusme si tedy příklad pro opakovaný výpis zprávy ještě jednou upravit, a to s využitím právě zmíněné instrukce LOOP. Výsledek bude vypadat takto:

org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
 
start:
        mov     cx, 10       ; pocatecni hodnota pocitadla
opak:
        ; tisk retezce na obrazovku
        mov     dx, message
        mov     ah, 9
        int     0x21
 
        loop    opak          ; snizeni pocitadla o jednicku
                              ; a skok, dokud se nedosahne nuly
 
        ; ukonceni procesu a navrat do DOSu
        mov     ah, 0x4c
        int     0x21
 
        ; retezec ukonceny znakem $
        ; (tato data jsou soucasti vysledneho souboru typu COM)
message db "Hello, world!", 0x0d, 0x0a, "$"

Vygenerovaný strojový kód ukáže i kódování a délku instrukce LOOP:

     1
     2                                  org  0x100        ; zacatek kodu pro programy typu COM (vzdy se zacina na 256)
     3
     4                                  start:
     5 00000000 B90A00                          mov     cx, 10       ; pocatecni hodnota pocitadla
     6                                  opak:
     7                                          ; tisk retezce na obrazovku
     8 00000003 BA[1000]                        mov     dx, message
     9 00000006 B409                            mov     ah, 9
    10 00000008 CD21                            int     0x21
    11
    12 0000000A E2F7                            loop    opak          ; snizeni pocitadla o jednicku
    13                                                                ; a skok, dokud se nedosahne nuly
    14
    15                                          ; ukonceni procesu a navrat do DOSu
    16 0000000C B44C                            mov     ah, 0x4c
    17 0000000E CD21                            int     0x21
    18
    19                                          ; retezec ukonceny znakem $
    20                                          ; (tato data jsou soucasti vysledneho souboru typu COM)
    21 00000010 48656C6C6F2C20776F-     message db "Hello, world!", 0x0d, 0x0a, "$"
    21 00000019 726C64210D0A24

17. Použití instrukce CMP v součinnosti s podmíněným skokem

Společně s podmíněnými skoky se velmi často používá doposud nepopsaná instrukce nazvaná CMP (mnemotechnická zkratka od slova compare). V podstatě se jedná o běžné celočíselné odečítání, tj. o instrukci nazvanou SUB, ovšem s tím důležitým rozdílem, že výsledek, tj. samotný rozdíl, není nikam zapsán, což znamená, že se obsah běžných pracovních registrů provedením této instrukce nezmění. Na první pohled může vypadat tato instrukce nesmyslně – proč se vůbec mají odečítat dvě hodnoty, když se výsledek hned zapomene? Ovšem samotný výsledek není ve skutečnosti vše, protože při odečítání si mikroprocesor v příznakových registrech zapamatuje i to, zda byla odečítaná čísla shodná (tehdy se nastaví Zero flag na jedničku) či zda byla druhá hodnota větší než hodnota první (příznak Carry flag bude v tomto případě roven jedné). Navíc se nastaví i další příznaky používané při práci s hodnotami se znaménkem.

Instrukce CMP akceptuje různé typy operandů; může se jednat o běžné pracovní registry, ovšem použít lze i konstanty či obsah získaný ze zvolené adresy operační paměti (platí zde tedy všechny výše zmíněné adresovací režimy). V následující tabulce si ukážeme, jaké základní příznaky se nastaví při provedení různých variant funkce CMP:

První operand Druhý operand Zero flag Carry flag Význam
00 00 1 0 obě hodnoty jsou shodné
42 42 1 0 obě hodnoty jsou shodné
20 10 0 0 první hodnota je větší (nedošlo k přenosu)
10 20 0 1 druhá hodnota je větší (došlo k přenosu)

Poznámka: ve skutečnosti by v tomto případě (odečítání a porovnávání) bylo korektnější mluvit o takzvané výpůjčce (borrow) a nikoli o přenosu (carry).

CS24 tip temata

Z těchto příkladů současně nepřímo vyplývá i to, jak můžeme příznakové bity použít. Jestliže je zapotřebí testovat dvě hodnoty na rovnost, postačí zjistit, zda je Zero flag nastavený na jedničku (ostatně i z tohoto důvodu má podmíněný skok JZ alias JE – jump if equal). Pokud potřebujeme otestovat, jestli je první hodnota menší než druhá, lze zjistit hodnotu příznaku Carry flag atd. Test na nulovou hodnotu lze provést odečtením nuly – výsledek bude uložen v Zero flagu (ve skutečnosti se ovšem tento test většinou neprovádí, protože i některé další instrukce dokážou nastavit tento příznak automaticky a vlastně „mimochodem“). Podobně je tomu u testování, zda je hodnota kladná či záporná. Podívejme se na několik možností použití:

; test na rovnost dvou hodnot
MOV AX, hodnota 1
MOV BX, hodnota 2
CMP AX, BX
JZ  JE_ROVNO    ; skok na kód provedený v případě rovnosti
JNZ NENI_ROVNO  ; skok na kód provedený v případě nerovnosti
; zjištění relace dvou čísel
MOV AX, hodnota 1
MOV BX, hodnota 2
CMP AX, BX
JNC AX_JE_VETSI_NEBO_ROVNO_BX
JC  AX_JE_MENSI_NEZ_BX
; test na nulovost
MOV AX, hodnota
SUB BX, BX       ; vynulování registru BX (lze i XOR BX,BX)
CMP AX, BX
JZ  AX_JE_NULOVE
; test na nulovost
MOV AX, hodnota
CMP AX, 0
JZ  AX_JE_NULOVE
; test na kladnou či zápornou hodnou
MOV AX, hodnota
CMP AX, 0
JS  AX_JE_ZAPORNE

18. Seznam již popsaných instrukcí

ADC Add with carry
ADD Add
AND Logical AND
CMP Compare operands
DEC Decrement by 1
DIV Unsigned divide
IDIV Signed divide
IMUL Signed multiply in One-operand form
INC Increment by 1
Jcc Jump if condition
JMP Jump
LOOP/LOOPx Loop control
MUL Unsigned multiply
NEG Two's complement negation
NOT Negate the operand, logical NOT
OR Logical OR
RCL Rotate left (with carry)
RCR Rotate right (with carry)
ROL Rotate left
ROR Rotate right
SAL Shift Arithmetically left (signed shift left)
SAR Shift Arithmetically right (signed shift right)
SBB Subtraction with borrow
SHL Shift left (unsigned shift left)
SHR Shift right (unsigned shift right)
SUB Subtraction
TEST Logical compare (AND)
XOR Exclusive OR

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

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.