SIMD instrukce na platformě 80×86: nepřímý důsledek platnosti Mooreova zákona

4. 2. 2025
Doba čtení: 69 minut

Sdílet

Intel microprocessor Pentium MMX 233 s architekturou P5 (P55C)
Autor: Raimond Spekking, podle licence: CC BY-SA 4.0
Začneme se seznamovat se SIMD instrukcemi pro platformu 80×86, které jsou souhrnně nazývány, i když ne zcela přesně, vektorové instrukce. První na řadě je technologie MMX.

Obsah

1. SIMD instrukce na platformě 80×86: nepřímý důsledek platnosti Mooreova zákona

2. Malá odbočka: Flynnova klasifikace sekvenčních a paralelních systémů

3. Kategorie SISD: základní způsob implementace skalárních procesorů CISC i RISC

4. Kategorie SIMD: procesory s podporou vektorových operací

5. Vektorové operace na platformě 80×86

6. Počty nových instrukcí v jednotlivých „vektorových“ rozšířeních instrukční sady

7. Instrukční sada MMX: první pokus o použití SIMD na platformě x86

8. Typy vektorů zpracovávaných instrukcemi MMX

9. Seznam instrukcí MMX

10. Registry MMX, vztah ke standardnímu matematickému koprocesoru

11. Vztah mezi registry MMX a registry matematického koprocesoru

12. Využití MMX v assembleru

13. Pomocný soubor s makry pro Linux a funkcí pro převod celočíselné hodnoty na hexadecimální řetězec

14. Načtení vektoru do MMX registru

15. Součet osmiprvkových vektorů s hodnotami typu byte

16. Výsledný vektor v případě přetečení

17. Součet osmiprvkových vektorů se saturací

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

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

20. Odkazy na Internetu

1. SIMD instrukce na platformě 80×86: nepřímý důsledek platnosti Mooreova zákona

„…sequential computers are approaching a fundamental physical limit on their potential power. Such a limit is the speed of light…“

Na sérii článků o matematických koprocesorech na platformě 80×86 dnes nepřímo navážeme. Začneme se totiž seznamovat se SIMD instrukcemi (taktéž s ohledem na platformu 80×86), které jsou zde souhrnně nazývány, i když ne zcela přesně, vektorové instrukce. Přitom SIMD/vektorové instrukce v současnosti patří ke standardní výbavě prakticky všech variant moderních mikroprocesorů a dokážou v některých případech několikanásobně urychlit výpočty.

Připomeňme si, že z hlediska dosahovaného výpočetního výkonu leží na samém „výkonnostním dně“ klasické mikroprocesory s architekturou CISC, které vykonávají všechny instrukce postupně a dokončení jedné instrukce může v závislosti na jejich složitosti trvat i několik desítek strojových taktů (což byl příklad Intelu 8086, kde například dělení trvalo 168 taktů + až dalších 16 taktů nutných pro výpočet efektivní adresy).

Předností těchto procesorů může být poměrně velká informační hustota instrukční sady (například i díky tomu, že operandy některých instrukcí jsou zadány implicitně), což mj. znamená, že se procesory tohoto typu po poměrně dlouhou dobu obešly bez nutnosti využití drahých vyrovnávacích pamětí první a druhé úrovně (L1 cache, L2 cache). Klasické procesory s architekturou CISC byly založeny na mikroprogramovém řadiči vybaveném pamětí mikroinstrukcí a teprve později začaly být tyto procesory doplňovány technologiemi získanými z jiných architektur – postupně se jednalo o instrukční fronty, instrukční pipeline, prediktor skoků, vektorové instrukce (což byly oblasti klasických RISCových architektur) atd.

Obrázek 1: Ukázka časování instrukce ADC (Add with carry) dnes již klasického osmibitového mikroprocesoru MOS 6502 s architekturou CISC. V závislosti na zvoleném adresním režimu se liší počty strojových cyklů od dvou do šesti. Liší se samozřejmě i počet bajtů nutných pro zakódování instrukce, protože některé adresní režimy vyžadují zápis absolutní šestnáctibitové adresy a jiné režimy naopak používají jen 8bitový offset, popř. osmibitovou adresu v rámci takzvané nulté stránky (zero page).

Výpočetní výkon mikroprocesorů se podařilo poměrně výrazným způsobem zvýšit u architektury RISC zavedením již výše zmíněné instrukční pipeline. Provedení jedné instrukce sice stále trvalo větší počet strojových cyklů, ovšem díky rozfázování operací v instrukční pipeline bylo umožněno překrývání většího množství instrukcí, a to bez nutnosti zavádění skutečné paralelizace (která vede k velkému nárůstu složitosti a tím i ceny čipu). Spolu se zavedením mikroprocesorů RISC se skutečně stalo, že reálný i špičkový výpočetní výkon procesorů vzrostl, ale relativně brzy bylo nutné k těmto čipům přidat vyrovnávací paměti (cache), jelikož rychlost procesorů rostla mnohem rychleji, než vybavovací doba pamětí. Navíc typické RISCové procesory měly instrukční slova o konstantní délce a tudíž obecně menší hustotu kódu. Tento rozpor mezi rychlostmi obou nejdůležitějších součástí moderních počítačů ostatně trvá dodnes.

Obrázek 2: Ukázka časování některých instrukcí šestnáctibitového mikroprocesoru Intel 8086 s architekturou CISC, kterým jsme se až doposud primárně zabývali. I přesto, že se jedná o procesor o generaci mladší, než MOS 6502, mají oba zmíněné typy čipů poměrně velké množství společných vlastností.

Pro další zvýšení výpočetního výkonu však bylo nutné použít další více či méně pokročilé technologie, například instrukční sadu VLIW, která však – opět – měla velké nároky na rychlost pamětí. Podobně jako u procesorů RISC, i u VLIW bylo pro zmírnění požadavků na rychlost pamětí možné použít Harvardskou architekturu, tj. odděleni paměti programu od paměti dat (programová paměť navíc mohla mít větší šířku datové sběrnice odpovídající šířce instrukčních slov). Další zvýšení výkonu umožňují právě vektorové instrukce (SIMD), které ale mají jeden poměrně zásadní nedostatek – takzvanou sémantickou mezeru mezi imperativním „skalárním“ kódem psaným například v jazyku C (C++ atd.) a instrukční sadou, která je SIMD (jinými slovy – běžné programovací jazyky neumožňují dostatečně popsat vektorové operace). Tuto mezeru do určité míry vyplňuje rozšíření GCC o takzvané intrinsic.

My ovšem budeme stále pracovat v assembleru, v němž žádná sémantická mezera mezi assemblerem a instrukcemi vlastně neexistuje, protože se přímo pracuje na úrovni instrukčního souboru daného mikroprocesoru.

Poznámka: ještě se o tom dále podrobněji zmíníme, ale příklady se SIMD instrukcemi už budou určeny pro Linux a nikoli pro DOS, protože mnoho emulátorů DOSu například nedokáže správně emulovat MMX atd.

Obrázek 3: Typický formát instrukcí procesorů s architekturou CISC spadajících do kategorie SISD. U většiny procesorů v kategorii CISC+SISD jsou použity instrukce s mnoha adresními režimy, instrukční slova proměnné délky a s proměnným počtem strojových cyklů nutných pro vykonání operace zakódované v instrukci.

2. Malá odbočka: Flynnova klasifikace sekvenčních a paralelních systémů

Před popisem vektorových instrukcí (resp. rozšiřujících sad s těmito instrukcemi) je vhodné se alespoň ve stručnosti zmínit o takzvané Flynnově klasifikaci sekvenčních a paralelních systémů. Jedná se o způsob rozdělení systémů (někdy se jedná o procesory, jindy o celé počítače či výpočetní uzly) v závislosti na tom, zda je tok instrukcí prováděn sekvenčně či paralelně a taktéž na tom, zda je tok dat prováděn sekvenčně či paralelně. Jinými slovy je Flynnova klasifikace založena na rozboru instrukčního a datového paralelismu zkoumaného procesoru/počítače/výpočetního uzlu/cloudu.

Sekvenční tok instrukcí se značí zkratkou SI (Single Instruction Stream), paralelní tok instrukcí pak zkratkou MI (Multiple Instructions Stream). Při charakterizaci toků dat se používá zkratka SD (Single Data Stream) pro sekvenční tok dat a zkratka MD (Multiple Data Stream) pro paralelní tok dat.

Poznámka: Flynnova klasifikace je sice již poměrně stará (poprvé byla představena již v roce 1966) a hrubá, ovšem stále se s ní můžeme setkat; především s jednou variantou SIMD, což jsou právě – když poněkud předběhneme – vektorové procesory nebo spíše vektorové subsystémy moderních procesorů.

Ve více než padesátileté historii vývoje výpočetní techniky se již objevily všechny čtyři možné kombinace instrukčního a datového paralelismu:

Zkratka klasifikace Anglický význam zkratky Využití systémů s danou klasifikací
SISD Single Instruction Stream, Single Data Stream klasická architektura pro procesory CISC a RISC
SIMD Single Instruction Stream, Multiple Data Stream vektorové procesory, GPU, procesory s instrukční sadou SSE/MMX…
MISD Multiple Instructions Stream, Single Data Stream poměrně speciální případy, řídicí počítače raketoplánů (Space Shuttle)
MIMD Multiple Instructions Stream, Multiple Data Stream Connection Machine, transputery, symetrické multiprocesory

Obrázek 4: U procesorů s instrukční sadou VLIW může být v jediném instrukčním slově (světle žlutý obdélník) uloženo větší množství operací. Na tomto obrázku je zobrazeno instrukční slovo hypotetického mikroprocesoru obsahujícího jeden modul pro komunikaci s pamětí, jednu ALU, matematický koprocesor a jednotku po provádění skoků. Spojování více operací do jednoho instrukčního slova je náplní práce překladače, přesněji řečeno jeho back endu (se všemi přednostmi i zápory, které toto řešení přináší).

3. Kategorie SISD: základní způsob implementace skalárních procesorů CISC i RISC

Z hlediska Flynnovy klasifikace patří mezi nejjednodušší systémy procesory a počítače ležící v kategorii SISD, která vlastně odpovídá klasické von Neumannově architektuře počítače. Do této kategorie spadají především původní mikroprocesory s architekturou CISC, ale i procesory RISC. Důvod, proč jsou oba tyto typy procesorů zařazeny do kategorie SISD, je jednoduchý – tyto čipy načítají instrukce z operační paměti sekvenčně a sekvenčně jsou taktéž vykonávány, samozřejmě s určitou výjimkou představovanou instrukční pipeline (tedy s překrýváním instrukcí). Nezávisle na konkrétním typu architektury procesoru jsou čipy patřící do kategorie SISD nejjednodušší jak z hlediska technické implementace a počtu tranzistorů, tak i nároky kladenými na překladač a v neposlední řadě i na vývojáře (kteří stále hledají vhodné prostředky pro vyjádření algoritmů určených pro paralelní systémy – tento problém totiž není ani zdaleka dobře vyřešen). Z tohoto hlediska se můžeme se systémy SISD stále v praxi setkávat a v mnoha oborech vlastně ani není důvod k přechodu k systémům složitějším a dražším.

Obrázek 5: Schéma systému patřícího do kategorie SISD.

Všechny CISCové mikroprocesory firmy Intel řady 80×86, od ještě z poloviny osmibitového čipu Intel 8088 (ten již dobře známe) až po model Intel 80486 (včetně) byly založeny na skalární architektuře SISD, stejně jako velké množství mikrořadičů či digitálních signálových procesorů (DSP – Digital Signal Processor). Nevýhodou systémů SISD ovšem je, že rychlost načítání a tím i zpracování instrukcí je shora omezena a že ani s využitím velmi dlouhé instrukční pipeline se nedá – vcelku logicky – překonat limit jedné zpracované instrukce za jeden takt. Příliš velké množství řezů (slices) pipeline má naopak i své zápory, především při zpracování skoků, návratů z podprogramů či odezvy na přerušení – ve všech těchto případech je nutné vyřešit problém, co se má udělat s instrukcemi, které se nachází v rozpracovaném stavu v pipeline (mohou se buď zahodit nebo naopak dokončit, podle toho, jakým způsobem byl lineární běh programu přerušen).

Obrázek 6: Sekvenční zpracování instrukcí, které jsou prováděny v několika fázích.

4. Kategorie SIMD: procesory s podporou vektorových operací

V současnosti se těší značné popularitě procesory patřící do kategorie SIMD, jejíž kořeny ovšem sahají hluboko do minulosti, konkrétně do šedesátých a sedmdesátých let minulého století (tato oblast výpočetní techniky je spojena se Symourem Crayem a jeho superpočítači Cray). Do této kategorie patří ty architektury procesorů, u kterých se s využitím jedné instrukce může zpracovat větší množství dat.

Například u rozšíření instrukční sady MMX, které si popíšeme v navazujících kapitolách, je možné s využitím jediné instrukce provést součet dvou vektorů číselných hodnot. Může se jednat o osm osmibitových hodnot uložených v jednom vektoru, čtyři šestnáctibitové hodnoty v jednom vektoru atd. (podrobnosti viz další text). Této vlastnosti se dá v mnoha případech využít pro urychlení běhu programů, protože některé algoritmy (ve skutečnosti je těchto algoritmů možná až udivující počet) provádí velké množství stejných operací s rozsáhlým objemem dat – například se může jednat o aplikaci konvolučního filtru na rastrový obrázek, zpracování zvukového signálu, vynásobení matice vektorem, vynásobení dvou matic, některé algoritmy z oblasti NLP (zpracování přirozeného jazyka) atd.

Obrázek 7: Schéma systému patřícího do kategorie SIMD.

Mezi přednosti čipů náležejících do kategorie SIMD patří jak relativně kompaktní instrukční sada, tak i paralelní a tím pádem i rychlý běh mnoha algoritmů, ovšem za cenu větších nároků kladených na programátora, popř. na překladač. Stále jen velmi malé množství programovacích jazyků totiž umožňuje explicitně vyjádřit vektorové či maticové operace (například u překladače Fortranu určeného pro superpočítače Cray bylo v manuálu explicitně řečeno, které jazykové konstrukce se budou skutečně provádět ve vektorové – SISD – jednotce) a jen některé překladače dokážou podobné optimalizace provádět kvalitně a automaticky.

Z tohoto důvodu také není možné většinu SIMD konstrukcí zapsat v konvenčním vyšším programovacím jazyce: musí se použít buď hotová makra, ručně optimalizované knihovní funkce nebo specializované programovací jazyky. Určitou, ale nezanedbatelnou výjimku představují GPU na grafických akcelerátorech, které explicitně pracují s 2D a 3D vektory, přičemž programátor může předem zjistit, které operace budou skutečně provedeny paralelně.

Obrázek 8: Typy vektorů, s nimiž pracují instrukce MMX popsané níže.

5. Vektorové operace na platformě 80×86

Jak jsme se již několikrát zmínili v předchozích odstavcích, jsou v soudobých typech mikroprocesorů (přesněji řečeno mikroprocesorů pro pracovní stanice i servery) implementovány i některé vektorové instrukce (popravdě řečeno již celkový počet vektorových instrukcí pravděpodobně překročil počet instrukcí skalárních, a to pravděpodobně několikanásobně :-). Pokud prozatím zůstaneme u platformy 80×86, tak historicky první instrukční sadou, přesněji řečeno doplněním či rozšířením původní instrukční sady, s podporou vektorových operací byla sada instrukcí MMX, s níž přišla firma Intel.

Poznámka: samotná zkratka MMX původně (oficiálně) neměla žádný význam, ovšem prakticky ihned po jejím uvedení se začala vykládat jako MultiMedia eXtension a později i Matrix Math eXtension, což jsou oba přiléhavé významy (navíc byly mikroprocesory s MMX označovány jako „multimediální procesory“).

Toto rozšíření instrukční sady sice umožňovalo provádění vektorových operací, ale mělo celou řadu omezení, především nízký počet „vektorových“ registrů, které navíc měly (z dnešního pohledu) malou bitovou šířku a z toho vycházející nízký počet prvků umístitelných ve vektorech atd. Nevýhodné taktéž bylo, že se pro instrukce MMX používaly registry určené původně pro práci s matematickým koprocesorem (FPU), takže současné provádění FP operací a MMX operací bylo minimálně složité; většinou i zcela nepraktické (na druhou stranu se však nemusely měnit operační systémy a jejich systém přepínáním úloh; totéž platí i pro přerušovací subrutiny). Ovšem poměrně brzy po uvedení sady MMX se objevila konkurenční instrukční sada 3Dnow! firmy AMD, která byla následovaná již zmíněnými sadami SSESSE5 a posléze několika generacemi AVX.

Obrázek 9: Dnes již historický mikroprocesor AMD K6–2 implementující mj. i rozšíření instrukční sady nazvané poněkud zvláštně 3Dnow!

Zkusme se nyní podívat na seznam různých SIMD (neboli nesprávně řečeno „vektorových“) rozšíření původní instrukční sady x86:

Technologie Rok uvedení Společnost Poprvé použito v čipu
MMX 1996 Intel Intel Pentium P5
3DNow! 1998 AMD AMD K6–2
SSE 1999 Intel Intel Pentium III (mikroarchitektura P6)
SSE2 2001 Intel Intel Pentium 4 (mikroarchitektura NetBurst)
SSE3 2004 Intel Intel Pentium 4 (Prescott)
SSSE3 2006 Intel mikroarchitektura Intel Core
SSE4 2006 Intel+AMD AMD K10 (SSE4a) , mikroarchitektura Intel Core
SSE5 2007 AMD (nakonec rozděleno do menších celků), mikroarchitektura Bulldozer
AVX 2008 Intel mikroarchitektura Sandy Bridge
F16C (CVT16) 2009 AMD Jaguar, Puma, Bulldozer atd.
XOP 2009 AMD mikroarchitektura Bulldozer
FMA3 2012 AMD mikroarchitektura Piledriver, Intel: Haswell a Broadwell
FMA4 2011 AMD mikroarchitektura Bulldozer (pozdější architektury po Zen 1 již ne)
AVX2 2013 Intel mikroarchitektura Haswell
AVX-512 2013 Intel Knights Landing
AMX 2020 Intel Sapphire Rapids

Informaci o tom, jaká rozšíření instrukční sady podporuje váš mikroprocesor, lze získat snadno:

$ cat /proc/cpuinfo

V mém konkrétním případě (Intel® Core™ i7–8665U CPU @ 1.90GHz) se vypíšou následující vlastnosti CPU. Z těchto příznaků jsem zdůraznil příznaky odpovídající SIMD instrukcím:

flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov
pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb
rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology
nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est
tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt
tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch
cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow
vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms
invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves
dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear
flush_l1d arch_capabilities

6. Počty nových instrukcí v jednotlivých „vektorových“ rozšířeních instrukční sady

Pro někoho může být taktéž zajímavá i informace o tom, jak velké změny v instrukční sadě mikroprocesorů byly vlastně při přidávání nových „vektorových“ rozšiřujících instrukčních sad typu SIMD provedeny. To nám ukáže další tabulka. Je pouze nutné dát si pozor na to, že počty nových instrukcí zavedených v rámci těchto nových technologií, které jsou vypsány v tabulce pod odstavcem, nemusí přesně souhlasit s počty uváděnými v jiných informačních materiálech.

Je tomu tak především z toho důvodu, že se v některých případech rozlišuje i datový typ, s nímž instrukce pracují (například se může jednat o součet vektoru s 32 bitovými hodnotami nebo 64bitovými hodnotami reprezentovanými v obou případech ve formátu s plovoucí řádovou čárkou) a někdy se taková instrukce do celkové sumy započítává pouze jedenkrát. Nicméně údaje vypsané v níže uvedené tabulce by měly být konzistentní, protože se jedná o počty nově přidaných operačních kódů instrukcí (například u dále popsané instrukční sady SSE2 končí instrukce znakem D, S, I či Q podle typu zpracovávaných dat/operandů):

Název technologie Počet nových instrukcí
MMX 56 (či 57 podle způsobu výpočtu)
3DNow! 21
SSE 70
SSE2 144
SSE3 13
SSSE3 32 (ve skutečnosti vlastně jen 16 instrukcí, ovšem pro dva datové typy)
SSE4 54 (z toho 47 v rámci SSE4.1, zbytek v rámci SSE4.2)
SSE5 170 (z toho 46 základních instrukcí)
F16C 4

7. Instrukční sada MMX: první pokus o použití SIMD na platformě x86

První rozšiřující instrukční sadou navrženou původně pro mikroprocesory na platformě x86 (tedy nikoli ještě x86–64), která obsahovala SIMD operace, je sada instrukcí nazvaná MMX (MultiMedia eXtension, později taktéž rozepisováno jako Matrix Math eXtension). Tato sada byla navržena již v roce 1996 společností Intel a od roku 1997 jí začaly být vybavovány prakticky všechny nové mikroprocesory této firmy, přesněji řečeno ty mikroprocesory, které patřily do rodiny x86 (připomeňme si, že se jednalo o 32bitové mikroprocesory, protože k rozšíření na 64bitovou ALU došlo u mainstreamových čipů až o několik let později). Prvním mikroprocesorem s plnou podporou MMX byl čip Pentium P55C nabízený od začátku roku 1997. Později došlo k implementaci instrukční sady MMX i na čipy Pentium II a procesory konkurenčních společností, konkrétně na čipy AMD K6 a taktéž na Cyrix M2 (6×86MX) a IDT C6.

Poznámka: na tomto místě je nutné poznamenat, že se vlastně nejednalo o nijak přelomovou technologii, protože v instrukční sadě MMX jsou použity instrukce analogické instrukcím ze SPARC VIS (VIS=Visual Instruction Set), MIPS MDMX či HP-PA MAX-1 a HP-PA MAX-2. Opět se tedy jedná o technologii inspirovanou RISCovými procesory – což není nic nového, protože prakticky všechny pokročilejší techniky byly dříve či později získány z tohoto zdroje.

Obrázek 10: Jedna z poměrně složitých, ale užitečných instrukcí z instrukční sady MMX. Jedná se konkrétně o instrukci PMADDWD, která provádí paralelní součin čtveřice šestnáctibitových hodnot s 32 bitovým mezivýsledkem, s následným součtem prvního + druhého a třetího + čtvrtého mezivýsledku. Tuto instrukci lze použít například při implementaci konvolučních filtrů.
(Zdroj: Intel MMXTM Technology Overview, Intel corporation, 1996)

8. Typy vektorů zpracovávaných instrukcemi MMX

Většina nových instrukcí přidaných v rámci sady MMX byla určena pro provádění aritmetických a bitových operací s celočíselnými operandy o šířce 8, 16, 32 či 64 bitů, což pokrývá poměrně širokou oblast multimediálních dat – osmibitových i šestnáctibitových zvukových vzorků (samplů), barev pixelů (RGB, RGBA) atd. Zatímco při provádění aritmetických operací s využitím klasické aritmeticko-logické jednotky mohlo docházet k přetečení či podtečení hodnot při provádění instrukcí typu ADD či SUB (součet, rozdíl), je možné u MMX instrukcí zvolit i takzvanou aritmetiku se saturací, což znamená, že v případě přetečení se do výsledku uloží maximální reprezentovatelná hodnota a naopak při podtečení minimální hodnota, což je například při zpracování signálu (většinou) žádoucí chování (příkladem může být zesvětlení či naopak ztmavení obrázku). V následující tabulce jsou vypsány nově podporované datové typy i způsob jejich uložení ve slovech o šířce 64 bitů, které jsou zpracovávány jednotkou MMX:

Datový typ Bitová šířka operandu Počet prvků vektoru
packed byte 8 bitů 8
packed word 16 bitů 4
packed doubleword 32 bitů 2
quadword 64 bitů 1
Poznámka: mnohé instrukce rozlišují mezi celočíselnými hodnotami se znaménkem a bez znaménka, tedy signed a unsigned. Podrobnosti si uvedeme v praktické části článku.

Obrázek 11: Ukázka jednoho typu konverzní funkce, kterých se v instrukční sadě MMX nachází několik.
(Zdroj: Intel MMXTM Technology Overview, Intel corporation, 1996)

Kromě přímé manipulace s celočíselnými hodnotami bylo relativně snadné pracovat i s numerickými hodnotami ukládanými ve formátu s pevnou řádovou čárkou (FX – fixed point), mohlo se například jednat o formáty 8.8 (osm bitů pro uložení celé části a osm bitů za řádovou čárkou), 8.24, 24.8 atd. O případné bitové posuny při normalizaci numerických hodnot se v tomto případě ovšem musel postarat programátor. Tyto formáty byly a jsou využívány v některých algoritmech implementujících FFT (rychlou Fourierovu transformaci využívanou v mnoha algoritmech pro zpracování signálů), DCT (diskrétní kosinovou transformaci využívanou například ve formátu JFIF-JPEG), FIR, IIR (filtry s konečnou a nekonečnou impulsní odezvou), operacemi nad vektory či operacemi nad maticemi.

Obrázek 12: Ukázka chování MMX instrukce nazvané PADDW, která provádí součet čtveřice šestnáctibitových hodnot s přetečením, což je patrné z posledního sloupce (tuto instrukci si ukážeme v praktických příkladech).
(Zdroj: Intel MMXTM Technology Overview, Intel corporation, 1996)

9. Seznam instrukcí MMX

Všech 57 instrukcí zavedených v instrukční sadě MMX lze rozdělit podle jejich funkce do několika skupin vypsaných v následující tabulce:

# Skupina instrukcí Příklady instrukcí
1 Základní aritmetické operace PADD, PADDS, PADDUS, PSUBS, PSUBUS, PMULHW, PMULLW
2 Logické (bitové) operace PAND, PANDN, POR, PXOR
3 Bitové posuny PSLL, PSRL, PSRA
4 Porovnávání PCMPEQ, PCMGT
5 Konverze dat PACKUSWB, PACKSS, PUNPCKH, PUNPCKL
6 Přenosy dat + práce s pamětí MOV (přesněji MOVD a MOVQ podle šířky dat)
7 Řízení jednotky MMX EMMS

Většina instrukcí uvedených v předchozí tabulce má navíc několik variant v závislosti na tom, s jakými operandy má instrukce ve skutečnosti pracovat. Například u instrukce PADD (tedy operace součtu) je možné zvolit, zda se mají sečíst dva osmiprvkové vektory, kde každý prvek má šířku 8 bitů, zda se má provést součet dvou čtyřprvkových vektorů (16bitové prvky), dvou dvouprvkových vektorů (32bitové prvky) či zda se jedná o součet dvojice 64bitových skalárních hodnot. To tedy znamená, že instrukce PADD může být reprezentována čtveřicí různých operačních kódů:

# Instrukce Význam
1 PADDB součet dvou vektorů majících osm osmibitových prvků
2 PADDW součet dvou vektorů majících čtyři šestnáctibitové prvky
3 PADDD součet dvou vektorů majících dva 32bitové prvky
4 PADDQ součet dvou 64bitových skalárních hodnot

Výjimkou z výše uvedeného pravidla jsou instrukce nazvané PAND, PANDN, POR a PXOR, pomocí nichž lze provádět bitové operace s dvojicí 64bitových slov. Důvod, proč není zapotřebí tyto instrukce dále rozdělovat podle počtu a šířky prvků vektorů, je zřejmý – tyto operace pracují nad jednotlivými bity, nikoli nad skupinami bitů. Na tomto místě je možná dobré upozornit na instrukci PANDN (not-and), která sice není ve většině běžných (skalárních) aritmeticko-logických jednotkách implementována, ovšem v případě zpracování rastrových obrazů se jedná o velmi užitečnou instrukci používanou například při vykreslování spritů atd.

Shrnutí: MMX je relativně snadno použitelné rozšíření instrukční sady, které zejména u multimediálních operací vede k poměrně razantnímu zvýšení výpočetního výkonu (teoreticky až osminásobné urychlení a při použití saturace i vyšší).

10. Registry MMX, vztah ke standardnímu matematickému koprocesoru

Inženýři ve firmě Intel stáli při návrhu instrukční sady MMX před požadavkem na vytvoření výkonných instrukcí provádějících SIMD operace, na druhou stranu však bylo nutné šetřit počtem tranzistorů a tím pádem i plochou čipu, na němž byl mikroprocesor vytvořen. Navíc bylo nutné zachovat kompatibilitu s existujícími programy a operačními systémy, zejména při ukládání registrů na zásobník v subrutinách atd. Pravděpodobně právě z tohoto důvodu se rozhodli učinit poněkud problematický krok – navrhli MMX instrukce takovým způsobem, aby mohly pracovat s osmicí 64bitových registrů rozdělených na jeden, dva, čtyři či osm prvků.

Ovšem nejednalo se, jak by se dalo předpokládat, o nové registry rozšiřující původní sadu registrů procesoru Pentium, ale o část registrů využívaných matematickým koprocesorem (FPU). Ten na platformě x86 prováděl operace s osmicí 80bitových registrů uspořádaných do zásobníku (u matematického koprocesoru Intel 8087 byly používány čistě zásobníkové instrukce doplněné o možnost specifikace druhého operandu, později byly přidány i další adresovací režimy, které umožňovaly registry adresovat přímo, což se ukázalo být výhodnější především kvůli možnostem provádění různých optimalizací).

V případě instrukcí MMX se sice registry adresovaly přímo (popř. se adresovala slova uložená v operační paměti, která mohla tvořit jeden z operandů instrukce), ale kvůli tomu, že jak FPU, tak i jednotka MMX pracovala se shodnými registry (horních 16 bitů těchto registrů nebylo v MMX využito), bylo současné používání SIMD operací a operací s hodnotami uloženými v systému plovoucí řádové čárky poměrně komplikované, což je škoda, protože právě souběžná práce superskalárního CPU (u mikroprocesorů Pentium byly vytvořeny dvě instrukční pipeline „u“ a „v“), jednotky MMX a navíc ještě matematického koprocesoru by v mnoha případech mohla vést k citelnému nárůstu výpočetního výkonu.

11. Vztah mezi registry MMX a registry matematického koprocesoru

V následující tabulce jsou vypsána jména registrů tak, jak jsou použita v instrukcích matematického koprocesoru, i ve formě používané jednotkou MMX::

Registr FPU bity 79–64 bity 63–0
ST0 nepoužito MM0
ST1 nepoužito MM1
ST2 nepoužito MM2
ST3 nepoužito MM3
ST4 nepoužito MM4
ST5 nepoužito MM5
ST6 nepoužito MM6
ST7 nepoužito MM7
Poznámka: s těmito názvy se můžeme setkat v disassemblovaném kódu, v debuggeru, nebo přímo při programování v assembleru.

12. Využití MMX v assembleru

V praktické části článku si ukážeme vybrané základní instrukce z rozšíření MMX. Ovšem oproti všem předchozím článkům, které byly v seriálu o vývoji pro PC prozatím vydány, nebudou tyto demonstrační příklady určeny pro operační systém DOS, ale pro Linux. Nejedná se o to, že by DOS instrukce MMX nepodporoval (lze je běžně využít i v reálném režimu a existuje i několik komerčních her, které je využívaly), ale některé emulátory PC a DOSu mají nedostatečnou podporu pro MMX a zejména pak pro rozšíření instrukčních sad SSE a AVX.

Z tohoto důvodu, alespoň pro tento okamžik, přejdeme z DOSu na Linux, přičemž ovšem díky použití assembleru NASM a jeho podpoře maker vlastně k žádným přelomovým změnám ve způsobu zápisu programů nedojde. Je tomu tak z toho důvodu, že volání služeb nabízených jádrem Linuxu bude „schováno“ do maker, podobně, jako jsme to dělali v DOSu. Jediným viditelnějším rozdílem je striktní oddělení kódu od inicializovaných dat i od dat neinicializovaných. To je řešeno takzvanými sekcemi TEXT (zde je uložen přeložený kód), DATA (inicializovaná data) a BSS (neinicializovaná data – nejsou uložena ve výsledném spustitelném binárním souboru).

Poznámka: navíc nám to umožní programy krokovat v debuggerech pro Linux, například v klasickém GNU Debuggeru. Ten totiž – na rozdíl od debuggerů pro DOS – MMX podporuje, což je vidět na výpisu registrů zobrazených při ladění dnešního druhého demonstračního příkladu:
info registers mm
 
mm0            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm1            {uint64 = 0x807060504030201, v2_int32 = {0x4030201, 0x8070605}, v4_int16 = {0x201, 0x403, 0x605, 0x807}, v8_int8 = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}}
mm2            {uint64 = 0x807060504030201, v2_int32 = {0x4030201, 0x8070605}, v4_int16 = {0x201, 0x403, 0x605, 0x807}, v8_int8 = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}}
mm3            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm4            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm5            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm6            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm7            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}

13. Pomocný soubor s makry pro Linux a funkcí pro převod celočíselné hodnoty na hexadecimální řetězec

Makra, která jsou použita pro volání služeb Linuxu, jsou uložena do zvláštního souboru nazvaného linux_macros.asm. Nalezneme zde i makro pro převod celočíselné hodnoty na hexadecimální řetězec, ovšem vlastní subrutina pro převod je uložena v jiném souboru (prozatím jsme totiž nepsali o tom, jak pracuje linker):

%ifndef LINUX_MACROS_LIB
%define LINUX_MACROS_LIB
 
; Linux kernel system call table
sys_exit  equ 1
sys_write equ 4
  
  
; makro pro tisk retezce na obrazovku
%macro print_string 2
        mov   eax, sys_write        ; cislo syscallu pro funkci "write"
        mov   ebx, 1                ; standardni vystup
        mov   ecx, %1               ; adresa retezce, ktery se ma vytisknout
        mov   edx, %2               ; delka retezce
        int   80h                   ; volani Linuxoveho kernelu
%endmacro
 
 
; makro pro tisk 32bitove hexadecimalni hodnoty
; na standardni vystup
%macro print_hex 2
        push ebx                    ; uschovat EBX pro dalsi pouziti
        mov     edx, %1             ; zapamatovat si hodnotu pro tisk
        mov     ebx, hex_message    ; buffer, ktery se zaplni hexa cislicemi
        mov     byte [ebx+8], %2    ; oddelovac, konec radku, atd.
        call    hex2string          ; zavolani prislusne subrutiny
        print_string   hex_message, hex_message_length    ; tisk hexadecimalni hodnoty
        pop ebx                     ; obnovit EBX
%endmacro
 
 
; makro pro vypis obsahu MMX vektoru
%macro print_mmx_reg_as_hex 1
        mov  ebx, mmx_tmp           ; adresa bufferu
        movq [ebx], %1              ; ulozeni do pameti (8 bajtu)
        mov  eax, [ebx+4]           ; nacteni casti MMX vektoru do celociselneho registru
        print_hex eax, ' '          ; zobrazeni obsahu tohoto registru v hexadecimalnim tvaru
        mov  eax, [ebx]             ; nacteni casti MMX vektoru do celociselneho registru
        print_hex eax, 0x0a         ; zobrazeni obsahu tohoto registru v hexadecimalnim tvaru
%endmacro
 
 
; makro pro ukonceni procesu 
%macro exit 0
        mov   eax,sys_exit          ; cislo sycallu pro funkci "exit"
        mov   ebx,0                 ; exit code = 0
        int   80h                   ; volani Linuxoveho kernelu
%endmacro
 
 
%endif

V dalším souboru hex2string.asm je uložena subrutina (podprogram) pro převod 32bitové hodnoty z registru EDX na hexadecimální vyjádření formou řetězce, jehož adresa je uložena v registru EBX:

%ifndef HEX_2_STRING_LIB
%define HEX_2_STRING_LIB
 
; subrutina urcena pro prevod 32bitove hexadecimalni hodnoty na retezec
; Vstup: EDX - hodnota, ktera se ma prevest na retezec
;        EBX - adresa jiz drive alokovaneho retezce (resp. osmice bajtu)
hex2string:
                  mov ecx,  8               ; pocet opakovani smycky
 
.print_one_digit: rol edx, 4                ; rotace doleva znamena, ze se do spodnich 4 bitu nasune dalsi cifra
                  mov al, dl                ; nechceme porusit obsah vstupni hodnoty v EDX, proto pouzijeme AL
                  and al, 0x0f              ; maskovani, potrebujeme pracovat jen s jednou cifrou
                  cmp al, 10                ; je cifra vetsi nebo rovna 10?
                  jl  .store_digit          ; neni, pouze prevest 0..9 na ASCII hodnotu '0'..'9'
 
.alpha_digit:     add al, 'A'-10-'0'        ; prevod hodnoty 10..15 na znaky 'A'..'F'
 
.store_digit:     add al, '0'
                  mov [ebx], al             ; ulozeni cifry do retezce
                  inc ebx                   ; dalsi cifra
                  loop .print_one_digit     ; a opakovani smycky, dokud se nedosahlo nuly
 
                  ret                       ; navrat ze subrutiny
 
%endif
Poznámka: předpokládá se použití 32bitového jádra, ovšem ve skutečnosti bude možné tyto programy přeložit a spustit i v 64bitovém Linuxu.

Pro překlad demonstračních příkladů slouží Makefile, který vypadá (ve zkrácené podobě) následovně:

ASM=nasm
LINKER=ld
 
execs := mmx_init mmx_paddb_1 mmx_paddb_2 mmx_paddusb
 
all:    $(execs)
 
clean:
        rm -f *.o $(execs)
 
.PHONY: all clean
 
%.o: %.asm linux_macros.asm hex2string.asm
        ${ASM} -f elf $< -o $@
 
mmx_init:       mmx_init.o
        ld -melf_i386 $< -o $@
 
mmx_paddb_1:    mmx_paddb_1.o
        ld -melf_i386 $< -o $@
 
mmx_paddb_2:    mmx_paddb_2.o
        ld -melf_i386 $< -o $@
 
mmx_paddusb:    mmx_paddusb.o
        ld -melf_i386 $< -o $@
Poznámka: linkeru je skutečně nutné předat parametr -f elf, aby se vynutil překlad pro 32bitový Linux. Pokud to neuděláte, strávíte (podobně jako autor článku) hodinu zjišťováním toho, proč se i tak základní instrukce, jakými jsou INC a DEC nechovají tak, jak už od roku 1978 mají :-)

14. Načtení vektoru do MMX registru

V dnešním prvním demonstračním příkladu si ukážeme, jakým způsobem se načítá vektor, konkrétně vektor osmi hodnot typu byte do zvoleného MMX registru. Na začátku programu pro jistotu zavoláme instrukci EMMS, která inicializuje tagy pro všechny FPU registry (které jsou sdíleny s MMX). Tuto instrukci je nutné zavolat i při opuštění kódu (například subrutiny), která s MMX pracuje, to však prozatím není náš problém:

        emms                         ; inicializace MMX

Samotné načtení vektoru je snadné. První instrukce načte adresu vektoru (v paměti) do zvoleného registru, například EBX (ale může jít i o jiný registr) a druhá instrukce MOVQ přesune všech osm bajtů do registru MM1 (z rozsahu MM0-MM7):

        mov ebx, mmx_val
        movq mm1, [ebx]              ; nacteni hodnoty do registru MM1

Vektor je uložen následovně:

mmx_val db 1, 2, 3, 4, 5, 6, 7, 8

Tento demonstrační příklad by po svém spuštění měl vypsat obsah registru MM1, a to takto:

08070605 04030201

Dvě 32bitové hexadecimální hodnoty jsou pro větší čitelnost odděleny mezerou. A za povšimnutí stojí, že se vektor do registru MMX načetl tak, jako by bylo uložen v pořadí little-endian, což odpovídá architektuře x86. Konkrétně poslední dvě číslice 01 odpovídají nejnižšímu prvku atd.

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

[bits 32]
 
%include "linux_macros.asm"
 
;-----------------------------------------------------------------------------
section .data
 
hex_message:
         times 8 db '?'
         db ' '
         hex_message_length equ $ - hex_message
  
mmx_val db 1, 2, 3, 4, 5, 6, 7, 8
 
;-----------------------------------------------------------------------------
section .bss
mmx_tmp resb 8
 
  
;-----------------------------------------------------------------------------
section .text
        global _start                ; tento symbol ma byt dostupny i linkeru
 
_start:
        emms                         ; inicializace MMX
        mov ebx, mmx_val
        movq mm1, [ebx]              ; nacteni hodnoty do registru MM1
        print_mmx_reg_as_hex mm1     ; tisk hodnoty registru MM1
 
        exit                         ; ukonceni procesu
 
 
%include "hex2string.asm"

15. Součet osmiprvkových vektorů s hodnotami typu byte

Ve druhém demonstračním příkladu je ukázán součet dvou osmiprvkových vektorů s hodnotami typu byte. Nejprve načteme dvojici vektorů do MMX registrů MM1 a MM2:

        mov ebx, mmx_val_1
        movq mm1, [ebx]              ; nacteni prvni hodnoty do registru MM1
 
        mov ebx, mmx_val_2
        movq mm2, [ebx]              ; nacteni druhe hodnoty do registru MM1

Načtení bude provedeno ze dvou paměťových oblastí:

mmx_val_1 db 1, 2, 3, 4, 5, 6, 7, 8
mmx_val_2 db 1, 2, 3, 4, 5, 6, 7, 8

Následně provedeme součet obou vektorů instrukcí PADDB, která provádí součet bajt po bajtu (tedy paralelně se sečte osm hodnot prvního vektoru s osmi hodnotami vektoru druhého):

        paddb mm1, mm2               ; soucet hodnot ve vektoru bajt po bajtu

Výsledky by měly vypadat následovně:

08070605 04030201
08070605 04030201
100E0C0A 08060402

Což lze chápat následovně:

první vektor:   08 07 06 05 04 03 02 01
druhý vektor:   08 07 06 05 04 03 02 01
součet vektorů: 10 0E 0C 0A 08 06 04 02
Poznámka: všechny hodnoty jsou zapsány hexadecimálně.

Opět si ukažme úplný zdrojový kód tohoto demonstračního příkladu:

[bits 32]
  
%include "linux_macros.asm"
 
;-----------------------------------------------------------------------------
section .data
 
hex_message:
         times 8 db '?'
         db ' '
         hex_message_length equ $ - hex_message
 
mmx_val_1 db 1, 2, 3, 4, 5, 6, 7, 8
mmx_val_2 db 1, 2, 3, 4, 5, 6, 7, 8
 
;-----------------------------------------------------------------------------
section .bss
mmx_tmp resb 8
 
 
;-----------------------------------------------------------------------------
section .text
        global _start                ; tento symbol ma byt dostupny i linkeru
 
_start:
        emms                         ; inicializace MMX
        mov ebx, mmx_val_1
        movq mm1, [ebx]              ; nacteni prvni hodnoty do registru MM1
        print_mmx_reg_as_hex mm1     ; tisk hodnoty registru MM1
 
        mov ebx, mmx_val_2
        movq mm2, [ebx]              ; nacteni druhe hodnoty do registru MM1
        print_mmx_reg_as_hex mm2     ; tisk hodnoty registru MM2
 
        paddb mm1, mm2               ; soucet hodnot ve vektoru bajt po bajtu
 
        print_mmx_reg_as_hex mm1     ; tisk hodnoty registru MM1
 
        exit                         ; ukonceni procesu
 
 
%include "hex2string.asm"

16. Výsledný vektor v případě přetečení

V předchozím demonstračním příkladu byly hodnoty vektorů zvoleny tak vhodně, že nedošlo k žádnému přetečení. Co se však stane v případě, kdy použijeme instrukci PADDB a hodnoty ve vektorech budou zvoleny tak vhodně, že dojde k přetečení? To si lze snadno otestovat:

mmx_val_1 db 1, 2, 3, 4, 5, 6, 7, 8
mmx_val_2 db 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb

Výsledky:

08070605 04030201
FBFBFBFB FBFBFBFB
03020100 FFFEFDFC

Což lze interpretovat následovně:

první vektor:   08 07 06 05 04 03 02 01
druhý vektor:   FB FB FB FB FB FB FB FB
součet vektorů: 03 02 01 00 FF FE FD FC
Poznámka: povšimněte si, že nikdy nedošlo k přenosu z jednoho (nižšího) bajtu do bajtu vyššího. Tím se instrukce PADDB odlišuje od běžného součtu dvou 64bitových hodnot.

Opět si ukažme úplný zdrojový kód tohoto demonstračního příkladu:

[bits 32]
 
%include "linux_macros.asm"
 
;-----------------------------------------------------------------------------
section .data
 
hex_message:
         times 8 db '?'
         db ' '
         hex_message_length equ $ - hex_message
 
mmx_val_1 db 1, 2, 3, 4, 5, 6, 7, 8
mmx_val_2 db 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb
 
;-----------------------------------------------------------------------------
section .bss
mmx_tmp resb 8
 
  
;-----------------------------------------------------------------------------
section .text
        global _start                ; tento symbol ma byt dostupny i linkeru
 
_start:
        emms                         ; inicializace MMX
        mov ebx, mmx_val_1
        movq mm1, [ebx]              ; nacteni prvni hodnoty do registru MM1
        print_mmx_reg_as_hex mm1     ; tisk hodnoty registru MM1
 
        mov ebx, mmx_val_2
        movq mm2, [ebx]              ; nacteni druhe hodnoty do registru MM1
        print_mmx_reg_as_hex mm2     ; tisk hodnoty registru MM2
 
        paddb mm1, mm2               ; soucet hodnot ve vektoru bajt po bajtu
 
        print_mmx_reg_as_hex mm1     ; tisk hodnoty registru MM1
 
        exit                         ; ukonceni procesu
 
 
%include "hex2string.asm"

17. Součet osmiprvkových vektorů se saturací

V multimediálních a DSP aplikacích je velmi užitečná i možnost sčítat a odčítat se saturací namísto přetečení. Podívejme se, proč jsou tyto operace v praxi velmi užitečné:

Obrázek 13: Zdrojový rastrový obrázek (známá fotografie Lenny), který tvoří zdroj pro jednoduchý konvoluční (FIR) filtr, jenž zvyšuje hodnoty pixelů o pevně zadanou konstantu (offset).

Obrázek 14: Pokud je pro přičtení offsetu použita operace součtu se zanedbáním přenosu (carry), tj. když se počítá systémem „modulo N“ (viz též výše zmíněná instrukce PADDB), dochází při překročení maximální hodnoty pixelu (čistě bílá barva) k viditelným chybám.

Obrázek 15: Při použití operace součtu se saturací sice dojde ke ztrátě informace (vzniknou oblasti s pixely majícími hodnotu 255), ovšem viditelná chyba je mnohem menší, než kdyby docházelo k přetečení (ostatně – dokážete chyby identifikovat?). Tento filtr by bylo možné realizovat s využitím instrukce PADDUSB s rychlostí výpočtu 8 pixelů/instrukci při bitové hloubce 8bpp.

Podívejme se tedy konkrétně na instrukci PADDUSB, která sčítá osmice bajtů se saturací. Vstupem jsou tyto dva vektory (totožné s předchozím příkladem):

mmx_val_1 db 1, 2, 3, 4, 5, 6, 7, 8
mmx_val_2 db 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb

Výsledek výpočtu:

první vektor:   08 07 06 05 04 03 02 01
druhý vektor:   FB FB FB FB FB FB FB FB
součet vektorů: FF FF FF FF FF FE FD FC
Poznámka: k saturaci dochází u prvních čtyř součtů.

Což je značně odlišné od součtu s přetečením, jaký jsme už viděli:

první vektor:   08 07 06 05 04 03 02 01
druhý vektor:   FB FB FB FB FB FB FB FB
součet vektorů: 03 02 01 00 FF FE FD FC

Ukažme si pro úplnost i tento zdrojový příklad:

[bits 32]
 
%include "linux_macros.asm"
 
;-----------------------------------------------------------------------------
section .data
 
hex_message:
         times 8 db '?'
         db ' '
         hex_message_length equ $ - hex_message
 
mmx_val_1 db 1, 2, 3, 4, 5, 6, 7, 8
mmx_val_2 db 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb
 
;-----------------------------------------------------------------------------
section .bss
mmx_tmp resb 8
 
 
;-----------------------------------------------------------------------------
section .text
        global _start                ; tento symbol ma byt dostupny i linkeru
 
_start:
        emms                         ; inicializace MMX
        mov ebx, mmx_val_1
        movq mm1, [ebx]              ; nacteni prvni hodnoty do registru MM1
        print_mmx_reg_as_hex mm1     ; tisk hodnoty registru MM1
 
        mov ebx, mmx_val_2
        movq mm2, [ebx]              ; nacteni druhe hodnoty do registru MM1
        print_mmx_reg_as_hex mm2     ; tisk hodnoty registru MM2
 
        paddusb mm1, mm2               ; soucet hodnot ve vektoru bajt po bajtu
 
        print_mmx_reg_as_hex mm1     ; tisk hodnoty registru MM1
 
        exit                         ; ukonceni procesu
 
 
%include "hex2string.asm"

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

Prozatím jsme si ukázali pouze naprosté základy rozšíření instrukční sady MMX. Příště budeme v popisu této sady pokračovat, přičemž si ukážeme velkou řadu různých demonstračních příkladů. Taktéž si ukážeme, jak lze vlastně detekovat, zda mikroprocesor vůbec MMX podporuje. Pro tento účel využijeme instrukci CPUID, která se pro tyto účely používá dodnes.

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
       
120 vga_320×200_image_0B.asm výsledek blokového přenosu ve chvíli, kdy je CX=0 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_0B.asm
121 vga_320×200_image_64kB.asm výsledek blokového přenosu ve chvíli, kdy je CX=0×ffff https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_64kB.asm
122 vga_320×200_image_movsb.asm blokový přenos v rámci obrazové paměti instrukcí REP MOVSB https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsb.asm
123 vga_320×200_image_movsw.asm blokový přenos v rámci obrazové paměti instrukcí REP MOVSW https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsw.asm
124 vga_320×200_image_movsd.asm blokový přenos v rámci obrazové paměti instrukcí REP MOVSD https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_movsd.asm
125 vga_320×200_image_movsb_forward.asm blokový přenos překrývajících se bloků paměti (zvyšující se adresy) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_mov­sb_forward.asm
126 vga_320×200_image_movsb_backward1.asm blokový přenos překrývajících se bloků paměti (snižující se adresy, nekorektní nastavení) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_mov­sb_backward1.asm
127 vga_320×200_image_movsb_backward2.asm blokový přenos překrývajících se bloků paměti (snižující se adresy, korektní nastavení) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_image_mov­sb_backward2.asm
       
128 sound_bell.asm přehrání zvuku pomocí tisku ASCII znaku BELL https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_bell.asm
129 sound_beep.asm přehrání zvuku o zadané frekvenci na PC Speakeru https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_beep.asm
130 sound_play_pitch.asm přehrání zvuku o zadané frekvenci na PC Speakeru, použití maker https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_play_pitch.asm
       
131 sound_opl2_basic.asm přehrání komorního A na OPL2 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_basic.asm
132 sound_opl2_table.asm přehrání komorního A na OPL2, použití tabulky s hodnotami registrů https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_table.asm
       
133 sound_opl2_table2.asm přepis tabulky s obsahy registrů pro přehrání komorního A https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_table2.asm
134 sound_key_on.asm přímé ovládání bitu KEY ON mezerníkem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_key_on.asm
135 sound_adsr.asm nastavení obálky pro tón přehrávaný prvním kanálem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_adsr.asm
136 sound_modulation.asm řízení frekvence modulátoru klávesami 1 a 0 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_modulation.asm
       
137 keyboard_basic.asm přímá práce s klávesnicí IBM PC https://github.com/tisnik/8bit-fame/blob/master/pc-dos/keyboard_basic.asm
       
138 sound_stereo_opl2.asm stereo zvuk v konfiguraci DualOPL2 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_stereo_opl2.asm
139 sound_opl2_multichannel.asm vícekanálový zvuk na OPL2 (klávesy), delší varianta https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_multichannel.asm
140 sound_opl2_multichannel2.asm vícekanálový zvuk na OPL2 (klávesy), kratší varianta https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl2_multichannel2.asm
141 sound_opl3_stereo1.asm stereo výstup na OPL3 (v kompatibilním režimu) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_stereo1.asm
142 sound_opl3_stereo2.asm stereo výstup na OPL3 (v režimu OPL3) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_stereo2.asm
143 sound_opl3_multichannel.asm vícekanálový zvuk na OPL3 (klávesy) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_multichannel.asm
       
144 sound_opl3_waveform1.asm interaktivní modifikace tvaru vlny u prvního operátoru https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform1.asm
145 sound_opl3_waveform2.asm oprava chyby: povolení režimu kompatibilního s OPL3 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform2.asm
146 sound_opl3_waveform3.asm vliv tvaru vln na zvukový kanál s FM syntézou https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform3.asm
147 sound_opl3_waveform4.asm modifikace tvaru vlny nosné vlny i modulátoru https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_waveform4.asm
148 sound_opl3_4operators1.asm výběr AM/FM režimu ve čtyřoperátorovém nastavení https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_4operators1.asm
149 sound_opl3_4operators2.asm výběr AM/FM režimu ve čtyřoperátorovém nastavení https://github.com/tisnik/8bit-fame/blob/master/pc-dos/sound_opl3_4operators2.asm
       
150 timer_basic.asm základní obsluha přerušení od časovače/čítače https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_basic.asm
151 timer_restore.asm obnovení původní obsluhy přerušení při ukončování aplikace https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_restore.asm
152 timer_restore_better_structure.asm refaktoring předchozího demonstračního příkladu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_restore_better_structure.asm
153 timer_faster_clock.asm zrychlení čítače na 100 přerušení za sekundu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/timer_faster_clock.asm
       
154 instruction_push_imm.asm instrukce PUSH s konstantou https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_imm.asm
155 instruction_imul_imm.asm instrukce IMUL s konstantou https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_imul_imm.asm
156 instruction_into1.asm instrukce INTO s obsluhou přerušení https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_into1.asm
157 instruction_into2.asm instrukce INTO s obsluhou přerušení https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_into2.asm
158 instruction_bound1.asm instrukce BOUND s obsluhou přerušení (nekorektní řešení) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bound1.asm
159 instruction_bound2.asm instrukce BOUND s obsluhou přerušení (korektní řešení) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bound2.asm
160 vga_320×200_putpixel286.asm instrukce bitového posunu s konstantou větší než 1 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_putpixel286.asm
161 instruction_push_pop.asm instrukce PUSH a POP se všemi pracovními registry https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_pop.asm
       
162 instruction_push_pop_B.asm instrukce s novými segmentovými registry https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_push_pop_B.asm
163 instruction_near_jz_jmp.asm blízké skoky https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_near_jz_jmp.asm
164 instruction_bsf.asm nová instrukce BSF https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bsf.asm
165 instruction_bsr.asm nová instrukce BSR https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_bsr.asm
166 instruction_add_32bit.asm 32bitový součet https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_add_32bit.asm
167 instruction_inc_32bit.asm 32bitová instrukce INC v šestnáctibitovém režimu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_inc_32bit.asm
168 instruction_inc_32bit_B.asm 32bitová instrukce INC v 32bitovém režimu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/instruction_inc_32bit_B.asm
       
169 ems_status.asm zjištění stavu (emulace) paměti EMS https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_status.asm
170 ems_total_mem.asm získání celkové kapacity paměti EMS v blocích https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_total_mem.asm
171 ems_free_mem.asm získání volné kapacity paměti EMS v blocích https://github.com/tisnik/8bit-fame/blob/master/pc-dos/ems_free_mem.asm
172 xms_free_mem.asm získání volné kapacity paměti XMS v blocích https://github.com/tisnik/8bit-fame/blob/master/pc-dos/xms_free_mem.asm
       
173 vga_320×200_short_address1.asm blokový přenos provedený v rámci prostoru segmentu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address1.asm
174 vga_320×200_short_address2.asm rozepsaný blokový přenos provedený v rámci prostoru segmentu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address2.asm
175 vga_320×200_short_address3.asm přenos nelze provést přes hranici offsetu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address3.asm
176 vga_320×200_short_address4.asm přenos nelze provést přes hranici offsetu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_short_address4.asm
177 vga_320×200_long_address1.asm 32bitový blokový přenos https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address1.asm
178 vga_320×200_long_address2.asm rozepsaný 32bitový blokový přenos provedený v rámci prostoru segmentu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address2.asm
179 vga_320×200_long_address3.asm přístup do obrazové paměti přes segment 0×0000 a 32bitový offset https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address3.asm
180 vga_320×200_long_address4.asm otestování, jak lze přenášet data s využitím 32bitového offsetu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/vga_320×200_long_address4.asm
       
181 print_msw.asm přečtení a zobrazení obsahu speciálního registru MSW https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print_msw.asm
182 print_cr0.asm přečtení a zobrazení obsahu speciálního registru CR0 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print_cr0.asm
183 prot_mode286.asm přechod do chráněného režimu na čipech Intel 80286 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode286.asm
184 prot_mode386.asm přechod do chráněného režimu na čipech Intel 80386 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode386.asm
185 prot_mode_back_to_real_mode286.asm přechod mezi reálným režimem a chráněným režimem i zpět na čipech Intel 80286 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_back_to_real_mo­de286.asm
186 prot_mode_back_to_real_mode386.asm přechod mezi reálným režimem a chráněným režimem i zpět na čipech Intel 80386 https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_back_to_real_mo­de386.asm
187 prot_mode_check.asm test, zda se mikroprocesor již nachází v chráněném režimu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/prot_mode_check.asm
188 unreal_mode.asm nastavení nereálného režimu (platné pro Intel 80386) https://github.com/tisnik/8bit-fame/blob/master/pc-dos/unreal_mode.asm
       
189 float32_constants.asm vytištění základních FP konstant typu single https://github.com/tisnik/8bit-fame/blob/master/pc-dos/float32_constants.asm
190 float64_constants.asm vytištění základních FP konstant typu double https://github.com/tisnik/8bit-fame/blob/master/pc-dos/float64_constants.asm
191 fpu_arithmetic.asm základní aritmetické operace prováděné matematickým koprocesorem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_arithmetic.asm
192 fpu_divide_by_zero.asm dělení nulou matematickým koprocesorem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_by_zero.asm
193 fpu_divide_by_neg_zero.asm dělení záporné hodnoty nulou matematickým koprocesorem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_by_neg_zero.asm
194 fpu_divide_by_neg_zero2.asm dělení hodnoty zápornou nulou matematickým koprocesorem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_by_neg_zero2.asm
195 fpu_divide_zero_by_zero.asm výpočet 0/0 matematickým koprocesorem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_zero_by_zero.asm
       
196 io.asm pomocná makra pro komunikaci s DOSem a BIOSem https://github.com/tisnik/8bit-fame/blob/master/pc-dos/io.asm
197 print.asm pomocná makra pro tisk FPU hodnot typu single a double v hexadecimálním tvaru https://github.com/tisnik/8bit-fame/blob/master/pc-dos/print.asm
       
198 fpu_divide.asm operace podílu https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide.asm
199 fpu_divide_r.asm operace podílu s prohozenými operandy https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_divide_r.asm
200 fpu_sqrt.asm výpočet druhé odmocniny https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_sqrt.asm
201 fpu_sqrt_neg_value.asm výpočet druhé odmocniny ze záporné hodnoty https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_sqrt_neg_value.asm
202 fpu_check.asm detekce typu matematického koprocesoru https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_check.asm
203 fpu_compare.asm porovnání dvou hodnot s vyhodnocením výsledku https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_compare.asm
204 fpu_status_word.asm tisk obsahu stavového slova koprocesoru https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_status_word.asm
205 fpu_status_word_stack.asm tisk obsahu stavového slova koprocesoru https://github.com/tisnik/8bit-fame/blob/master/pc-dos/fpu_status_word_stack.asm
       
206 Makefile https://github.com/tisnik/8bit-fame/blob/master/pc-linux/Makefile
207 hex2string.asm subrutina pro převod 32bitové hexadecimální hodnoty na řetězec https://github.com/tisnik/8bit-fame/blob/master/pc-linux/hex2string.asm
208 linux_macros.asm pomocná makra pro tvorbu aplikací psaných v assembleru pro Linux https://github.com/tisnik/8bit-fame/blob/master/pc-linux/linux_macros.asm
209 mmx_init.asm inicializace subsystému MMX https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_init.asm
210 mmx_paddb1.asm zavolání MMX instrukce pro součet vektorů bajtů (bez přetečení) https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddb1.asm
211 mmx_paddb2.asm zavolání MMX instrukce pro součet vektorů bajtů (s přetečením) https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddb2.asm
212 mmx_paddusb.asm zavolání MMX instrukce pro součet vektorů bajtů se saturací https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddusb.asm
213 mmx_paddw.asm zavolání MMX instrukce pro součet vektorů šestnáctibitových slov https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddw.asm
214 mmx_paddd.asm zavolání MMX instrukce pro součet vektorů 32bitových slov https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddd.asm
215 mmx_paddq.asm zavolání MMX instrukce pro součet 64bitových slov https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddq.asm
216 mmx_paddx.asm porovnání operací součtu pro vektory s prvky různých typů https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddx.asm
217 mmx_support.asm zjištění, zda je MMX podporována https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_support.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. DOS API (Wikipedia)
    https://en.wikipedia.org/wiki/DOS_API
  17. Bit banging
    https://en.wikipedia.org/wi­ki/Bit_banging
  18. IBM Basic assembly language and successors (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Basic_assembly_lan­guage_and_successors
  19. X86 Assembly/Bootloaders
    https://en.wikibooks.org/wi­ki/X86_Assembly/Bootloaders
  20. Počátky grafiky na PC: grafické karty CGA a Hercules
    https://www.root.cz/clanky/pocatky-grafiky-na-pc-graficke-karty-cga-a-hercules/
  21. 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/
  22. Karta EGA: první použitelná barevná grafika na PC
    https://www.root.cz/clanky/karta-ega-prvni-pouzitelna-barevna-grafika-na-pc/
  23. RGB Classic Games
    https://www.classicdosgames.com/
  24. Turbo Assembler (Wikipedia)
    https://en.wikipedia.org/wi­ki/Turbo_Assembler
  25. Microsoft Macro Assembler
    https://en.wikipedia.org/wi­ki/Microsoft_Macro_Assembler
  26. IBM Personal Computer (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Personal_Computer
  27. Intel 8251
    https://en.wikipedia.org/wi­ki/Intel_8251
  28. Intel 8253
    https://en.wikipedia.org/wi­ki/Intel_8253
  29. Intel 8255
    https://en.wikipedia.org/wi­ki/Intel_8255
  30. Intel 8257
    https://en.wikipedia.org/wi­ki/Intel_8257
  31. Intel 8259
    https://en.wikipedia.org/wi­ki/Intel_8259
  32. Support/peripheral/other chips – 6800 family
    http://www.cpu-world.com/Support/6800.html
  33. Motorola 6845
    http://en.wikipedia.org/wi­ki/Motorola_6845
  34. The 6845 Cathode Ray Tube Controller (CRTC)
    http://www.tinyvga.com/6845
  35. CRTC operation
    http://www.6502.org/users/an­dre/hwinfo/crtc/crtc.html
  36. The 6845 Cathode Ray Tube Controller (CRTC)
    http://www.tinyvga.com/6845
  37. Motorola 6845 and bitwise graphics
    https://retrocomputing.stac­kexchange.com/questions/10996/mo­torola-6845-and-bitwise-graphics
  38. IBM Monochrome Display Adapter
    http://en.wikipedia.org/wi­ki/Monochrome_Display_Adap­ter
  39. Color Graphics Adapter
    http://en.wikipedia.org/wi­ki/Color_Graphics_Adapter
  40. 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/
  41. The Modern Retrocomputer: An Arduino Driven 6845 CRT Controller
    https://hackaday.com/2017/05/14/the-modern-retrocomputer-an-arduino-driven-6845-crt-controller/
  42. flat assembler: Assembly language resources
    https://flatassembler.net/
  43. FASM na Wikipedii
    https://en.wikipedia.org/wiki/FASM
  44. Fresh IDE FASM inside
    https://fresh.flatassembler.net/
  45. MS-DOS Version 4.0 Programmer's Reference
    https://www.pcjs.org/docu­ments/books/mspl13/msdos/dos­ref40/
  46. DOS API (Wikipedia)
    https://en.wikipedia.org/wiki/DOS_API
  47. IBM Basic assembly language and successors (Wikipedia)
    https://en.wikipedia.org/wi­ki/IBM_Basic_assembly_lan­guage_and_successors
  48. X86 Assembly/Arithmetic
    https://en.wikibooks.org/wi­ki/X86_Assembly/Arithmetic
  49. Art of Assembly – Arithmetic Instructions
    http://oopweb.com/Assembly/Do­cuments/ArtOfAssembly/Volu­me/Chapter6/CH06–2.html
  50. ASM Flags
    http://www.cavestory.org/gu­ides/csasm/guide/asm_flag­s.html
  51. Status Register
    https://en.wikipedia.org/wi­ki/Status_register
  52. Linux assemblers: A comparison of GAS and NASM
    http://www.ibm.com/develo­perworks/library/l-gas-nasm/index.html
  53. Programovani v assembleru na OS Linux
    http://www.cs.vsb.cz/gryga­rek/asm/asmlinux.html
  54. Is it worthwhile to learn x86 assembly language today?
    https://www.quora.com/Is-it-worthwhile-to-learn-x86-assembly-language-today?share=1
  55. Why Learn Assembly Language?
    http://www.codeproject.com/Ar­ticles/89460/Why-Learn-Assembly-Language
  56. Is Assembly still relevant?
    http://programmers.stackex­change.com/questions/95836/is-assembly-still-relevant
  57. Why Learning Assembly Language Is Still a Good Idea
    http://www.onlamp.com/pub/a/on­lamp/2004/05/06/writegreat­code.html
  58. Assembly language today
    http://beust.com/weblog/2004/06/23/as­sembly-language-today/
  59. Assembler: Význam assembleru dnes
    http://www.builder.cz/rubri­ky/assembler/vyznam-assembleru-dnes-155960cz
  60. Programming from the Ground Up Book – Summary
    http://savannah.nongnu.or­g/projects/pgubook/
  61. DOSBox
    https://www.dosbox.com/
  62. The C Programming Language
    https://en.wikipedia.org/wi­ki/The_C_Programming_Langu­age
  63. Hercules Graphics Card (HCG)
    https://en.wikipedia.org/wi­ki/Hercules_Graphics_Card
  64. Complete 8086 instruction set
    https://content.ctcd.edu/cou­rses/cosc2325/m22/docs/emu8086in­s.pdf
  65. Complete 8086 instruction set
    https://yassinebridi.github.io/asm-docs/8086_instruction_set.html
  66. 8088 MPH by Hornet + CRTC + DESiRE (final version)
    https://www.youtube.com/wat­ch?v=hNRO7lno_DM
  67. Area 5150 by CRTC & Hornet (Party Version) / IBM PC+CGA Demo, Hardware Capture
    https://www.youtube.com/wat­ch?v=fWDxdoRTZPc
  68. 80×86 Integer Instruction Set Timings (8088 – Pentium)
    http://aturing.umcs.maine­.edu/~meadow/courses/cos335/80×86-Integer-Instruction-Set-Clocks.pdf
  69. Colour Graphics Adapter: Notes
    https://www.seasip.info/Vin­tagePC/cga.html
  70. Restoring A Vintage CGA Card With Homebrew HASL
    https://hackaday.com/2024/06/12/res­toring-a-vintage-cga-card-with-homebrew-hasl/
  71. Demoing An 8088
    https://hackaday.com/2015/04/10/de­moing-an-8088/
  72. Video Memory Layouts
    http://www.techhelpmanual.com/89-video_memory_layouts.html
  73. Screen Attributes
    http://www.techhelpmanual.com/87-screen_attributes.html
  74. IBM PC Family – BIOS Video Modes
    https://www.minuszerodegre­es.net/video/bios_video_mo­des.htm
  75. EGA Functions
    https://cosmodoc.org/topics/ega-functions/#the-hierarchy-of-the-ega
  76. 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/
  77. How 16 colors saved PC gaming – the story of EGA graphics
    https://www.custompc.com/retro-tech/ega-graphics
  78. List of 16-bit computer color palettes
    https://en.wikipedia.org/wi­ki/List_of16-bit_computer_color_palettes
  79. 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
  80. VGA Color Palettes
    https://www.fountainware.com/EX­PL/vga_color_palettes.htm
  81. Hardware Level VGA and SVGA Video Programming Information Page
    http://www.osdever.net/Fre­eVGA/vga/vga.htm
  82. Hardware Level VGA and SVGA Video Programming Information Page – sequencer
    http://www.osdever.net/Fre­eVGA/vga/seqreg.htm
  83. VGA Basics
    http://www.brackeen.com/vga/ba­sics.html
  84. Introduction to VGA Mode ‚X‘
    https://web.archive.org/web/20160414072210/htt­p://fly.srk.fer.hr/GDM/ar­ticles/vgamodex/vgamx1.html
  85. VGA Mode-X
    https://web.archive.org/web/20070123192523/htt­p://www.gamedev.net/referen­ce/articles/article356.asp
  86. Mode-X: 256-Color VGA Magic
    https://downloads.gamedev­.net/pdf/gpbb/gpbb47.pdf
  87. Instruction Format in 8086 Microprocessor
    https://www.includehelp.com/embedded-system/instruction-format-in-8086-microprocessor.aspx
  88. 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
  89. VGA Hardware
    https://wiki.osdev.org/VGA_Hardware
  90. Programmer's Guide to Yamaha YMF 262/OPL3 FM Music Synthesizer
    https://moddingwiki.shika­di.net/wiki/OPL_chip
  91. 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/
  92. Yamaha YMF262 OPL3 music – MoonDriver for OPL3 DEMO [Oscilloscope View]
    https://www.youtube.com/watch?v=a7I-QmrkAak
  93. Yamaha OPL vs OPL2 vs OPL3 comparison
    https://www.youtube.com/wat­ch?v=5knetge5Gs0
  94. OPL3 Music Crockett's Theme
    https://www.youtube.com/wat­ch?v=HXS008pkgSQ
  95. Bad Apple (Adlib Tracker – OPL3)
    https://www.youtube.com/wat­ch?v=2lEPH6Y3Luo
  96. FM Synthesis Chips, Codecs and DACs
    https://www.dosdays.co.uk/to­pics/fm_synthesizers.php
  97. The Zen Challenge – YMF262 OPL3 Original (For an upcoming game)
    https://www.youtube.com/wat­ch?v=6JlFIFz1CFY
  98. [adlib tracker II techno music – opl3] orbit around alpha andromedae I
    https://www.youtube.com/wat­ch?v=YqxJCu_WFuA
  99. [adlib tracker 2 music – opl3 techno] hybridisation process on procyon-ii
    https://www.youtube.com/wat­ch?v=daSV5mN0sJ4
  100. Hyper Duel – Black Rain (YMF262 OPL3 Cover)
    https://www.youtube.com/wat­ch?v=pu_mzRRq8Ho
  101. IBM 5155–5160 Technical Reference
    https://www.minuszerodegre­es.net/manuals/IBM/IBM_5155_5160_Techni­cal_Reference_6280089_MAR86­.pdf
  102. a ymf262/opl3+pc speaker thing i made
    https://www.youtube.com/watch?v=E-Mx0lEmnZ0
  103. [OPL3] Like a Thunder
    https://www.youtube.com/wat­ch?v=MHf06AGr8SU
  104. (PC SPEAKER) bad apple
    https://www.youtube.com/wat­ch?v=LezmKIIHyUg
  105. Powering devices from PC parallel port
    http://www.epanorama.net/cir­cuits/lptpower.html
  106. Magic Mushroom (demo pro PC s DOSem)
    http://www.crossfire-designs.de/download/articles/sou­ndcards//mushroom.rar
  107. Píseň Magic Mushroom – originál
    http://www.crossfire-designs.de/download/articles/sou­ndcards/speaker_mushroom_con­verted.mp3
  108. Píseň Magic Mushroom – hráno na PC Speakeru
    http://www.crossfire-designs.de/download/articles/sou­ndcards/speaker_mushroom_spe­aker.mp3
  109. Pulse Width Modulation (PWM) Simulation Example
    http://decibel.ni.com/content/docs/DOC-4599
  110. Resistor/Pulse Width Modulation DAC
    http://www.k9spud.com/trax­mod/pwmdac.php
  111. Class D Amplifier
    http://en.wikipedia.org/wi­ki/Electronic_amplifier#Clas­s_D
  112. Covox Speech Thing / Disney Sound Source (1986)
    http://www.crossfire-designs.de/index.php?lang=en&what=ar­ticles&name=showarticle.htm&ar­ticle=soundcards/&page=5
  113. Covox Digital-Analog Converter (Rusky, obsahuje schémata)
    http://phantom.sannata.ru/kon­kurs/netskater002.shtml
  114. PC-GPE on the Web
    http://bespin.org/~qz/pc-gpe/
  115. Keyboard Synthesizer
    http://www.solarnavigator­.net/music/instruments/ke­yboards.htm
  116. FMS – Fully Modular Synthesizer
    http://fmsynth.sourceforge.net/
  117. Javasynth
    http://javasynth.sourceforge.net/
  118. Software Sound Synthesis & Music Composition Packages
    http://www.linux-sound.org/swss.html
  119. Mx44.1 Download Page (software synthesizer for linux)
    http://hem.passagen.se/ja_linux/
  120. Software synthesizer
    http://en.wikipedia.org/wi­ki/Software_synthesizer
  121. Frequency modulation synthesis
    http://en.wikipedia.org/wi­ki/Frequency_modulation_syn­thesis
  122. Yamaha DX7
    http://en.wikipedia.org/wi­ki/Yamaha_DX7
  123. Wave of the Future
    http://www.wired.com/wired/ar­chive/2.03/waveguides_pr.html
  124. Analog synthesizer
    http://en.wikipedia.org/wi­ki/Analog_synthesizer
  125. Minimoog
    http://en.wikipedia.org/wiki/Minimoog
  126. Moog synthesizer
    http://en.wikipedia.org/wi­ki/Moog_synthesizer
  127. Tutorial for Frequency Modulation Synthesis
    http://www.sfu.ca/~truax/fmtut.html
  128. An Introduction To FM
    http://ccrma.stanford.edu/sof­tware/snd/snd/fm.html
  129. John Chowning
    http://en.wikipedia.org/wi­ki/John_Chowning
  130. I'm Impressed, Adlib Music is AMAZING!
    https://www.youtube.com/wat­ch?v=PJNjQYp1ras
  131. Milinda- Diode Milliampere ( OPL3 )
    https://www.youtube.com/wat­ch?v=oNhazT5HG0E
  132. Dune 2 – Roland MT-32 Soundtrack
    https://www.youtube.com/wat­ch?v=kQADZeB-z8M
  133. Interrupts
    https://wiki.osdev.org/In­terrupts#Types_of_Interrup­ts
  134. Assembly8086SoundBlasterDma­SingleCycleMode
    https://github.com/leonardo-ono/Assembly8086SoundBlas­terDmaSingleCycleMode/blob/mas­ter/sbsc.asm
  135. Interrupts in 8086 microprocessor
    https://www.geeksforgeeks­.org/interrupts-in-8086-microprocessor/
  136. Interrupt Structure of 8086
    https://www.eeeguide.com/interrupt-structure-of-8086/
  137. A20 line
    https://en.wikipedia.org/wi­ki/A20_line
  138. Extended memory
    https://en.wikipedia.org/wi­ki/Extended_memory#eXtended_Me­mory_Specification_(XMS)
  139. Expanded memory
    https://en.wikipedia.org/wi­ki/Expanded_memory
  140. Protected mode
    https://en.wikipedia.org/wi­ki/Protected_mode
  141. Virtual 8086 mode
    https://en.wikipedia.org/wi­ki/Virtual_8086_mode
  142. Unreal mode
    https://en.wikipedia.org/wi­ki/Unreal_mode
  143. DOS memory management
    https://en.wikipedia.org/wi­ki/DOS_memory_management
  144. Upper memory area
    https://en.wikipedia.org/wi­ki/Upper_memory_area
  145. Removing the Mystery from SEGMENT : OFFSET Addressing
    https://thestarman.pcminis­try.com/asm/debug/Segments­.html
  146. Segment descriptor
    https://en.wikipedia.org/wi­ki/Segment_descriptor
  147. When using a 32-bit register to address memory in the real mode, contents of the register must never exceed 0000FFFFH. Why?
    https://stackoverflow.com/qu­estions/45094696/when-using-a-32-bit-register-to-address-memory-in-the-real-mode-contents-of-the
  148. A Brief History of Unreal Mode
    https://www.os2museum.com/wp/a-brief-history-of-unreal-mode/
  149. Segment Limits
    https://wiki.osdev.org/Segment_Limits
  150. How do 32 bit addresses in real mode work?
    https://forum.osdev.org/vi­ewtopic.php?t=30642
  151. The LOADALL Instruction by Robert Collins
    https://www.rcollins.org/ar­ticles/loadall/tspec_a3_doc­.html
  152. How do you put a 286 in Protected Mode?
    https://retrocomputing.stac­kexchange.com/questions/7683/how-do-you-put-a-286-in-protected-mode
  153. Control register
    https://en.wikipedia.org/wi­ki/Control_register
  154. CPU Registers x86
    https://wiki.osdev.org/CPU_Re­gisters_x86
  155. x86 Assembly/Protected Mode
    https://en.wikibooks.org/wi­ki/X86_Assembly/Protected_Mo­de
  156. MSW: Machine Status Word
    https://web.itu.edu.tr/kes­gin/mul06/intel/intel_msw­.html
  157. 80×87 Floating Point Opcodes
    http://www.techhelpmanual.com/876–80×87_floating_point_opcodes.html
  158. Page Translation
    https://pdos.csail.mit.edu/6­.828/2005/readings/i386/s05_02­.htm
  159. 80386 Paging and Segmenation
    https://stackoverflow.com/qu­estions/38229741/80386-paging-and-segmenation
  160. 80386 Memory Management
    https://tldp.org/LDP/khg/Hy­perNews/get/memory/80386mm­.html
  161. DOSEMU
    http://www.dosemu.org/
  162. Intel 80386, a revolutionary CPU
    https://www.xtof.info/intel80386.html
  163. PAI Unit 3 Paging in 80386 Microporcessor
    https://www.slideshare.net/Kan­chanPatil34/pai-unit-3-paging-in-80386-microporcessor
  164. 64 Terabytes of virtual memory for 32-bit x86 using segmentation: how?
    https://stackoverflow.com/qu­estions/5444984/64-terabytes-of-virtual-memory-for-32-bit-x86-using-segmentation-how
  165. Pi in the Pentium: reverse-engineering the constants in its floating-point unit
    http://www.righto.com/2025/01/pentium-floating-point-ROM.html
  166. Simply FPU
    http://www.website.masmfo­rum.com/tutorials/fptute/
  167. Art of Assembly language programming: The 80×87 Floating Point Coprocessors
    https://courses.engr.illi­nois.edu/ece390/books/arto­fasm/CH14/CH14–3.html
  168. Art of Assembly language programming: The FPU Instruction Set
    https://courses.engr.illi­nois.edu/ece390/books/arto­fasm/CH14/CH14–4.html
  169. INTEL 80387 PROGRAMMER'S REFERENCE MANUAL
    http://www.ragestorm.net/dow­nloads/387intel.txt
  170. x86 Instruction Set Reference: FLD
    http://x86.renejeschke.de/html/fi­le_module_x86_id100.html
  171. x86 Instruction Set Reference: FLD1/FLDL2T/FLDL2E/FLDPI/­FLDLG2/FLDLN2/FLDZ
    http://x86.renejeschke.de/html/fi­le_module_x86_id101.html
  172. X86 Assembly/Arithmetic
    https://en.wikibooks.org/wi­ki/X86_Assembly/Arithmetic
  173. 8087 Numeric Data Processor
    https://www.eeeguide.com/8087-numeric-data-processor/
  174. Data Types and Instruction Set of 8087 co-processor
    https://www.eeeguide.com/data-types-and-instruction-set-of-8087-co-processor/
  175. 8087 instruction set and examples
    https://studylib.net/doc/5625221/8087-instruction-set-and-examples
  176. GCC documentation: Extensions to the C Language Family
    https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions
  177. GCC documentation: Using Vector Instructions through Built-in Functions
    https://gcc.gnu.org/online­docs/gcc/Vector-Extensions.html
  178. SSE (Streaming SIMD Extentions)
    http://www.songho.ca/misc/sse/sse­.html
  179. Timothy A. Chagnon: SSE and SSE2
    http://www.cs.drexel.edu/~tc365/mpi-wht/sse.pdf
  180. Intel corporation: Extending the Worldr's Most Popular Processor Architecture
    http://download.intel.com/techno­logy/architecture/new-instructions-paper.pdf
  181. SIMD architectures:
    http://arstechnica.com/ol­d/content/2000/03/simd.ar­s/
  182. Tour of the Black Holes of Computing!: Floating Point
    http://www.cs.hmc.edu/~ge­off/classes/hmc.cs105…/sli­des/class02_floats.ppt
  183. 3Dnow! Technology Manual
    AMD Inc., 2000
  184. Intel MMXTM Technology Overview
    Intel corporation, 1996
  185. MultiMedia eXtensions
    http://softpixel.com/~cwrig­ht/programming/simd/mmx.phpi
  186. AMD K5 („K5“ / „5k86“)
    http://www.pcguide.com/ref/cpu/fam/g5K5-c.html
  187. Sixth Generation Processors
    http://www.pcguide.com/ref/cpu/fam/g6­.htm
  188. Great Microprocessors of the Past and Present
    http://www.cpushack.com/CPU/cpu1.html
  189. Very long instruction word (Wikipedia)
    http://en.wikipedia.org/wi­ki/Very_long_instruction_word
  190. CPU design (Wikipedia)
    http://en.wikipedia.org/wi­ki/CPU_design
  191. Bulldozer (microarchitecture)
    https://en.wikipedia.org/wi­ki/Bulldozer_(microarchitec­ture)
  192. MMX (instruction set)
    https://en.wikipedia.org/wi­ki/MMX_(instruction_set)
  193. Extended MMX
    https://en.wikipedia.org/wi­ki/Extended_MMX
Neutrální ikona do widgetu na odběr článků ze seriálů

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.