Obsah
1. Rozšíření instrukční sady SSE2 (dokončení)
2. Přečtení příznaku záporné hodnoty pro všechny bajty ve 128bitovém vektoru
3. První demonstrační příklad – výsledky instrukce PMOVMSKB
4. Extrakce a proložení prvků o šířce 64bitů ze 128bitových vektorů
5. Druhý demonstrační příklad – výsledky instrukce UNPCKHPD
6. Třetí demonstrační příklad – výsledky instrukce UNPCKLPD
7. Extrakce a proložení jednotlivých bajtů ze 128bitových vektorů
8. Čtvrtý demonstrační příklad – výsledky instrukce PUNPCKHBW
9. Pátý demonstrační příklad – výsledky instrukce PUNPCKLBW
10. Komplikovanější proložení prvků vektorů instrukcí PSHUFD
11. Šestý demonstrační příklad – výsledky instrukce PSHUFD pro různé konstanty
12. Okomentované výsledky šestého příkladu
13. Praktické použití instrukcí popsaných v předchozích kapitolách
14. Přičtení konstanty ke všem bajtům ve 128bitovém vektoru
15. Rozšíření předchozího příkladu na dvojici 128bitových vektorů
16. Skalární součin osmibitových hodnot uložených ve dvojici 128bitových vektorů
19. Repositář s demonstračními příklady
1. Rozšíření instrukční sady SSE2 (dokončení)
Na předchozí dvojici článků o rozšíření instrukční sady SSE2 [1] [2] dnes navážeme. Popíšeme si některé zbývající instrukce, které je možné v SSE2 nalézt. Ty již většinou neslouží k provádění „klasických“ vektorových operací typu „součet odpovídajících si prvků dvou vektorů“ nebo „porovnání odpovídajících si prvků dvou vektorů“; jedná se naopak o operace pro prokládání prvků, extrakci či naopak spojování prvků vektorů atd. Možnosti instrukční sady SSE2 jsou sice v tomto ohledu poněkud neefektivní (vyřešeno až v AVX-512), ovšem tyto instrukce jsou často používány, zejména pro operace typu scan nebo reduce (součet všech prvků vektorů, nalezení maximálního prvku, provedení skalárního součinu atd.).
2. Přečtení příznaku záporné hodnoty pro všechny bajty ve 128bitovém vektoru
První instrukce, kterou se dnes budeme zabývat, vlastně nepatří ani do jedné z kategorií zmíněných v úvodním odstavci. Tato instrukce se jmenuje PMOVMSKB a akceptuje dva operandy – 128bitový vektor XMM a standardní pracovní registr CPU (například EAX atd.). PMOVMSKB z každého bajtu 128bitového vektoru získá informaci o znaménku a tu uloží na příslušné místo do pracovního registru. Vzhledem k tomu, že do 128bitového vektoru je možné uložit šestnáct bajtů, budou informace o znaménku (1=záporná hodnota, 0=kladná hodnota) uloženy v nejnižších šestnácti bitech zvoleného pracovního registru.
Některé instrukce v sadě SSE2 (ale nikoli všechny) existují ve více variantách, které se od sebe liší typem prvků vektorů (bajt, slovo, dvouslovo, čtyřslovo). Instrukce PMOVMSKB ovšem žádnou další variantu nemá a ani to vlastně není zapotřebí. Pokud se totiž zpracovává například vektor s prvky typu slovo, postačuje z výsledku přečíst sudé příznaky znaménka a ty liché ignorovat. Totéž platí i pro další typy prvků (a to včetně hodnot float a double).
3. První demonstrační příklad – výsledky instrukce PMOVMSKB
V dnešním prvním demonstračním příkladu jsou ukázány výsledky vypočtené instrukcí PMOVMSKB popsané v předchozí kapitole. Vektor bajtů, u nichž se bude zjišťovat jejich znaménko, obsahuje hodnoty 0×00, 0×10 až 0×f0, tj. polovina hodnot je kladná a polovina záporná (resp. je lze interpretovat jako záporné hodnoty). Výsledkem bude šestnáct příznakových bitů, které jsou uloženy do registru EAX, jehož obsah je následně vypsán na standardní výstup:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 db 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1 ; adresa prvniho vektoru
movdqu xmm0, [ebx] ; nacteni puvodniho vektoru do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
pmovmskb eax, xmm0 ; ziskani priznaku znamenka pro vsechny bajty ve vektoru
print_hex eax, 13 ; tisk registru eax, v jehoz spodnich 16 bitech jsou priznaky
exit ; ukonceni procesu
%include "hex2string.asm"
Podívejme se na vypsané hodnoty:
F0E0D0C0 B0A09080 70605040 30201000 0000FF00
Ty lze interpretovat takto:
bajt: F0 E0 D0 C0 B0 A0 90 80 70 60 50 40 30 20 10 00 znaménko: 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
Z výsledků je patrné, že příznak zápornosti je skutečně nastaven korektně.
4. Extrakce a proložení prvků o šířce 64bitů ze 128bitových vektorů
Další dvě instrukce, které si dnes popíšeme a taktéž otestujeme, se jmenují UNPCKHPD a UNPCKLPD. Pravidelní čtenáři tohoto seriálu již pravděpodobně rozpoznávají způsob rozklíčování jmen těchto instrukcí: UNPCK znamená unpack, H znamená high values (tedy horní prvky vektorů), L pochopitelně znamená low, P znamená packed (vektorová operace, nikoli skalární) a konečně D je označení datového typu prvků, tedy v tomto případě double. Ze jména instrukcí lze tedy odvodit, že jsou určeny pro přečtení horního nebo dolního prvku typu double z vektoru, který obsahuje dvě takové hodnoty. A vzhledem k tomu, že se jedná o vektorovou operaci, je přečtení horního/dolního prvku provedeno na dvojici vstupních vektorů, přičemž výsledkem bude nová 128bitová hodnota.
5. Druhý demonstrační příklad – výsledky instrukce UNPCKHPD
V dnešním druhém demonstračním příkladu si ukážeme, jakým způsobem se prokládají 64bitové prvky dvou vektorů do jediného 128bitového vektoru. Přitom je použita instrukce UNPCKHPD a vektory budou mít obsah:
vektor1: 0x1111111111111111 0x2222222222222222 vektor2: 0x3333333333333333 0x4444444444444444
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
align 16
sse_val_1 dq 0x1111111111111111, 0x2222222222222222
sse_val_2 dq 0x3333333333333333, 0x4444444444444444
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1 ; adresa prvniho vektoru
movdqu xmm0, [ebx] ; nacteni puvodniho vektoru do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_2 ; adresa druheho vektoru
movdqu xmm1, [ebx] ; nacteni puvodniho vektoru do registru XMM1
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM0
unpckhpd xmm0, xmm1 ; ziskani hornich polovin z obou vektoru
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
exit ; ukonceni procesu
%include "hex2string.asm"
Podívejme se nyní na výsledky, které získáme po spuštění příkladu. Popis jednotlivých řádků byl dodán ručně (zbytečně by komplikoval zdrojový kód):
vektor 1: 2222222222222222 1111111111111111
vektor 2: 4444444444444444 3333333333333333
výsledek: 4444444444444444 2222222222222222
význam: vektor2 vektor1
(vyšší prvek) (vyšší prvek)
6. Třetí demonstrační příklad – výsledky instrukce UNPCKLPD
Třetí příklad, který si dnes ukážeme, je prakticky totožný s příkladem předchozím, ovšem namísto instrukce UNPCKHPD je zde použita instrukce UNPCKLPD. Záměna znaku H za L značí, že do výsledného vektoru budou uloženy nižší (low) prvky typu double a nikoli vyšší (high) prvky. To si snadno ověříme:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 dq 0x1111111111111111, 0x2222222222222222
sse_val_2 dq 0x3333333333333333, 0x4444444444444444
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1 ; adresa prvniho vektoru
movdqu xmm0, [ebx] ; nacteni puvodniho vektoru do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_2 ; adresa druheho vektoru
movdqu xmm1, [ebx] ; nacteni puvodniho vektoru do registru XMM1
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM0
unpcklpd xmm0, xmm1 ; ziskani dolnich polovin z obou vektoru
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
exit ; ukonceni procesu
%include "hex2string.asm"
Opět se podívejme na výsledky:
vektor 1: 22222222 22222222 11111111 11111111
vektor 2: 44444444 44444444 33333333 33333333
výsledek: 33333333 33333333 11111111 11111111
význam: vektor2 vektor1
(nižší prvek) (nižší prvek)
7. Extrakce a proložení jednotlivých bajtů ze 128bitových vektorů
V předchozím textu jsme se věnovali popisu a testování instrukcí nazvaných UNPCKHPD a UNPCKLPD, které pracují s vektory obsahující dvojice hodnot typu double. Instrukční sada SSE2 sice není plně ortogonální, ale obsahuje podobné instrukce pracující s vektory s odlišným typem a tím pádem i počtem prvků (vlastně kromě typu float – tyto instrukce totiž byly obsaženy již v původní sadě SSE). Pro extrakci a proložení prvků, které jsou typu bajt (a je jich tedy ve vektorech uloženo vždy šestnáct) slouží instrukce nazvané PUNPCKHBW a PUNPCKLBW.
To může vypadat zvláštně, protože bychom čekali, že jméno bude stejné, jako v případě UNPCKHPD/UNPCKLPD, pouze se bude lišit poslední znak (B-byte namísto D-double). Není tomu tak z historických důvodů, protože instrukce PUNPCKHBW/PUNPCKLBW původně pochází z instrukční sady MMX a pro účely SSE2 byly rozšířeny registry, s nimiž se pracuje, na dvojnásobnou šířku (svět architektury x86 je ostatně plný podobných překvapení a historických důvodů).
8. Čtvrtý demonstrační příklad – výsledky instrukce PUNPCKHBW
Vyzkoušejme si nejdříve chování instrukce PUNPCKHBW. Její název dokážeme do značné míry rozklíčovat – extrakce horních bajtů z dvojice vektorů a uložení těchto bajtů do vektoru cílového. Přičemž je otázkou, co považovat za horní bajty (napoví poslední znak W nebo spíš zmate čtenáře?). To ovšem jasně ukážou výsledky:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 db 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1, 0xf1
sse_val_2 db 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0xa2, 0xb2, 0xc2, 0xd2, 0xe2, 0xf2
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1 ; adresa prvniho vektoru
movdqu xmm0, [ebx] ; nacteni puvodniho vektoru do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_2 ; adresa druheho vektoru
movdqu xmm1, [ebx] ; nacteni puvodniho vektoru do registru XMM1
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM0
punpckhbw xmm0, xmm1 ; provedeni operace prolozeni hodnot z obou vektoru po bajtech
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
exit ; ukonceni procesu
%include "hex2string.asm"
Výsledky vypsané tímto příkladem jsou přeformátovány a doplněny o komentáře:
vektor 1: F1 E1 D1 C1 B1 A1 91 81 71 61 51 41 31 21 11 01 vektor 2: F2 E2 D2 C2 B2 A2 92 82 72 62 52 42 32 22 12 02 výsledek: F2 F1 E2 E1 D2 D1 C2 C1 B2 B1 A2 A1 92 91 82 81
Do výsledného vektoru byly uloženy jen vyšší poloviny z obou vstupních vektorů (tedy high) a navíc byly proloženy. Tj. nejnižší bajt výsledného vektoru obsahuje devátý bajt z vektoru prvního, dále devátý bajt z vektoru druhého atd.
9. Pátý demonstrační příklad – výsledky instrukce PUNPCKLBW
Vzhledem k tomu, že jsme si právě ukázali výsledky činnosti instrukce PUNPCKHBW, je zřejmé, že si ukážeme i výsledky instrukce pojmenované PUNPCKLBW. Opět platí, že záměna znaku H za znak L naznačuje, že se do výsledného vektoru budou ukládat nižší prvky obou vstupních vektorů. To si snadno ověříme:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 db 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1, 0xf1
sse_val_2 db 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0xa2, 0xb2, 0xc2, 0xd2, 0xe2, 0xf2
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1 ; adresa prvniho vektoru
movdqu xmm0, [ebx] ; nacteni puvodniho vektoru do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
mov ebx, sse_val_2 ; adresa druheho vektoru
movdqu xmm1, [ebx] ; nacteni puvodniho vektoru do registru XMM1
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM0
punpcklbw xmm0, xmm1 ; provedeni operace prolozeni hodnot z obou vektoru po bajtech
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
exit ; ukonceni procesu
%include "hex2string.asm"
Podívejme se na okomentované výsledky získané tímto příkladem:
vektor 1: F1 E1 D1 C1 B1 A1 91 81 71 61 51 41 31 21 11 01 vektor 2: F2 E2 D2 C2 B2 A2 92 82 72 62 52 42 32 22 12 02 výsledek: 72 71 62 61 52 51 42 41 32 31 22 21 12 11 02 01
Z výsledného vektoru je patrné, že se skutečně proložily jen spodní prvky obou vstupních vektorů – z každého vektoru se přečetlo osm nižších prvků a ty byly proloženy do výsledku.
10. Komplikovanější proložení prvků vektorů instrukcí PSHUFD
Jednou z nejkomplikovanějších instrukcí v sadě SSE2 je instrukce pojmenovaná PSHUFD, což je zkratka značící shuffle packed doublewords (mimochodem: znak D má někdy význam doubleword a jindy double precision float, protože konzistence je přece v IT tak důležitá). Tato instrukce pracuje pouze s jedním zdrojovým vektorem a vybírá z něho prvky na základě bitového pole, které je druhým operandem této instrukce. V tomto bitovém poli je uloženo osm bitů rozdělených do čtyř skupin. Z toho vyplývá, že každá skupina má dva bity a tedy obsahuje hodnoty 0–3.
Prvky vstupního vektoru si můžeme označit takto: X=[x3, x2, x1, x0]. A hodnoty v osmibitové konstantě rozdělené do čtyř skupin si můžeme označit: s3, s2, s1 a s0 (každá hodnota je v rozsahu 0–3). Výsledný vektor bude obsahovat tyto hodnoty:
[X[s3], X[s2], X[s1], X[s0]]
Tedy například pokud bude s3=0, s2=3, s1=1, s0=1, dostaneme:
[X[0], X[3], X[1], X[1]] = [x0, x3, x1, x1]
Vidíme, že tato instrukce dokáže zdvojit/ztrojit prvky, zpřeházet je, otočit jejich pořadí atd. Jediným omezením je, že ono bitové pole s hodnotami s3, s2, s1 a s0 je v instrukčním slovu uloženo formou konstanty (a nejde tedy jednoduše modifikovat).
11. Šestý demonstrační příklad – výsledky instrukce PSHUFD pro různé konstanty
V pořadí již šestém demonstračním příkladu si ukážeme výsledky získané instrukcí PSHUFD v případě, že druhým operandem této instrukce je konstanta od 0 do 15. Musí se skutečně jednat o konstantu, takže nebylo možné použít počítanou programovou smyčku (kód je v současnosti uložen v neměnitelných sekcích, takže ho nelze snadno modifikovat za běhu). Vstupem je vždy stejný vektor s obsahem:
0x11111111, 0x22222222, 0x33333333, 0x44444444
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 dd 0x11111111, 0x22222222, 0x33333333, 0x44444444
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1 ; adresa prvniho vektoru
movdqu xmm0, [ebx] ; nacteni puvodniho vektoru do registru XMM0
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 0 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 1 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 2 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 3 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 4 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 5 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 6 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 7 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 8 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 9 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 10 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 11 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 12 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 13 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 14 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
pshufd xmm1, xmm0, 15 ; prolozeni obsahu dvou vektoru
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
exit ; ukonceni procesu
%include "hex2string.asm"
12. Okomentované výsledky šestého příkladu
Podívejme se nyní na výsledky vypsané dnešním šestým demonstračním příkladem, které byly navíc okomentovány:
původní vektor: 44444444 33333333 22222222 11111111 s3=0, s2=0, s1=0, s0=0: 11111111 11111111 11111111 11111111 nejvyšší tři prvky = nultý prvek původního vektoru s3=0, s2=0, s1=0, s0=1: 11111111 11111111 11111111 22222222 nejnižší prvek = vybíraný různě podle indexu 0-3 s3=0, s2=0, s1=0, s0=2: 11111111 11111111 11111111 33333333 s3=0, s2=0, s1=0, s0=3: 11111111 11111111 11111111 44444444 s3=0, s2=0, s1=1, s0=0: 11111111 11111111 22222222 11111111 nejvyšší dva prvky = nultý prvek původního vektoru s3=0, s2=0, s1=1, s0=1: 11111111 11111111 22222222 22222222 druhý nejnižší prvek = první prvek původního vektoru s3=0, s2=0, s1=1, s0=2: 11111111 11111111 22222222 33333333 nejnižší prvek = vybíraný různě podle indexu 0-3 s3=0, s2=0, s1=1, s0=3: 11111111 11111111 22222222 44444444 s3=0, s2=0, s1=2, s0=0: 11111111 11111111 33333333 11111111 nejvyšší dva prvky = nultý prvek původního vektoru s3=0, s2=0, s1=2, s0=1: 11111111 11111111 33333333 22222222 druhý nejnižší prvek = druhý prvek původního vektoru s3=0, s2=0, s1=2, s0=2: 11111111 11111111 33333333 33333333 nejnižší prvek = vybíraný různě podle indexu 0-3 s3=0, s2=0, s1=2, s0=3: 11111111 11111111 33333333 44444444 s3=0, s2=0, s1=3, s0=0: 11111111 11111111 44444444 11111111 nejvyšší dva prvky = nultý prvek původního vektoru s3=0, s2=0, s1=3, s0=1: 11111111 11111111 44444444 22222222 druhý nejnižší prvek = nejvyšší prvek původního vektoru s3=0, s2=0, s1=3, s0=2: 11111111 11111111 44444444 33333333 nejnižší prvek = vybíraný různě podle indexu 0-3 s3=0, s2=0, s1=3, s0=3: 11111111 11111111 44444444 44444444
13. Praktické použití instrukcí popsaných v předchozích kapitolách
Instrukce, s nimiž jsme se dnes seznámili, slouží pro různé manipulace a kombinace prvků vektorů. Mohlo by se zdát, že tyto instrukce jsou používány spíše výjimečně, ovšem v SSE2 nemáme k dispozici instrukce, které by dokázaly provést broadcasting. To je označení používané například v knihovně Numpy, kde značí operaci mezi skalární hodnotou a vektorem – operace je provedena postupně se všemi prvky vektoru, které jsou nějakým způsobem zkombinovány se skalární hodnotou. A taktéž v instrukční sadě SSE2 nenalezneme instrukce typu scan či reduce, tedy postupnou aplikaci nějaké operace na všechny prvky vektoru (příkladem je součet všech prvků vektoru nebo asi známější skalární součin). Právě v těchto oblastech si musíme vystačit s instrukcemi, které jsme si až doposud popsali – což nemusí být vždy triviální.
14. Přičtení konstanty ke všem bajtům ve 128bitovém vektoru
Výběr instrukcí, které jsme si popsali v předchozích kapitolách, není náhodný, protože tři z nich, konkrétně PUNPCKHBW, PUNPCKLBW a PSHUFD jsou použity v dalším příkladu, který provede přičtení konstanty ke všem bajtům 128bitového vektoru. Samotné přičtení je pochopitelně realizováno „vektorově“ instrukcí PADDB, ovšem nejdříve musíme nějakým způsobem ze skalární konstanty zkonstruovat vektor obsahující tu samou opakující se hodnotu:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1 ; adresa vektoru
movdqu xmm1, [ebx] ; nacteni puvodniho vektoru do registru XMM0
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
mov esi, 1 ; konstanta, kterou budeme pricitat
movd xmm0, esi ; nacteni konstanty do druheho vektoru
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
punpcklbw xmm0, xmm0 ; prolozeni hodnot, zdrojem je jediny registr
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
punpcklwd xmm0, xmm0 ; prolozeni hodnot, zdrojem je jediny registr
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
pshufd xmm0, xmm0, 0 ; rozkopirovani spodnich osmi bajtu do celeho vektoru
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
paddb xmm0, xmm1 ; vektorovy soucet
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
exit ; ukonceni procesu
%include "hex2string.asm"
Prováděná operace je zřejmá z vypsaných vstupních dat, mezivýsledků a výsledků:
vstupní vektor: 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00 přičítaná konstanta: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 první proložení hodnot: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 druhé proložení hodnot: 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 rozkopírování dvojslova: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 výsledek: 10 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01
15. Rozšíření předchozího příkladu na dvojici 128bitových vektorů
V předchozím příkladu bylo nutné použít trojici vektorových instrukcí PUNPCKHBW, PUNPCKLBW a PSHUFD jen pro to, aby se ze skalární konstanty stal vektor totožných prvků. To se může zdát jako poměrně mnoho práce s relativně malým užitkem. Výhodou ovšem je, že ve chvíli, kdy již máme připraven vektor s totožnými prvky, je možné ho využít pro přičtení konstant k delším polím. Například rozšíření přičtení konstanty ze šestnácti prvků na 32 prvků spočívá v přidání pouze jediné vektorové instrukce PADD, takže se „přípravná práce“ lépe amortizuje:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
sse_val_2 db 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1 ; adresa prvniho vektoru
movdqu xmm1, [ebx] ; nacteni puvodniho vektoru do registru XMM1
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
mov ebx, sse_val_2 ; adresa druheho vektoru
movdqu xmm2, [ebx] ; nacteni puvodniho vektoru do registru XMM0
print_sse_reg_as_hex xmm2 ; tisk hodnoty registru XMM2
mov esi, 1 ; konstanta, kterou budeme pricitat
movd xmm0, esi ; nacteni konstanty do druheho vektoru
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
punpcklbw xmm0, xmm0 ; prolozeni hodnot, zdrojem je jediny registr
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
punpcklwd xmm0, xmm0 ; prolozeni hodnot, zdrojem je jediny registr
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
pshufd xmm0, xmm0, 0 ; rozkopirovani spodnich osmi bajtu do celeho vektoru
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
paddb xmm1, xmm0 ; vektorovy soucet
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM0
paddb xmm2, xmm0 ; vektorovy soucet
print_sse_reg_as_hex xmm2 ; tisk hodnoty registru XMM0
exit ; ukonceni procesu
%include "hex2string.asm"
Opět si ukážeme okomentované výsledky:
první vstupní vektor: 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00 druhý vstupní vektor: 1F 1E 1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10 přičítaná konstanta: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 první proložení hodnot: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 druhé proložení hodnot: 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 rozkopírování dvojslova: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 přičtení k prvnímu vektoru: 10 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 přičtení ke druhému vektoru: 20 1F 1E 1D 1C 1B 1A 19 18 17 16 15 14 13 12 11
16. Skalární součin osmibitových hodnot uložených ve dvojici 128bitových vektorů
Na závěr si vyzkoušíme, jakým způsobem by se mohl realizovat algoritmus skalárního součinu osmibitových hodnot uložených ve dvojici 128bitových vektorů (tedy každý vektor má v tomto případě šestnáct prvků). Nejedná se o náhodně vybraný algoritmus, protože výpočet skalárního součinu nalezneme v AI, velkých jazykových modelech, algoritmech počítačové grafiky, zpracování signálu atd.
V jazyku C by mohl být tento výpočet realizován takto:
unsigned char dot_product_16bytes(unsigned char *a, unsigned char *b) {
#define SIZE 16
int i;
unsigned char result = 0;
for (i=0; i<SIZE; i++) {
result += a[i] * b[i];
}
return result;
}
17. Přepis do assembleru
Zadání problému bylo napsáno takovým způsobem, aby nebylo možné jednoduše nahradit operaci násobení za jedinou instrukci. Je tomu tak z toho důvodu, že neexistuje vektorová instrukce pro vynásobení vektorů bajtů. Proto je řešení relativně složité a k výsledku vede celá řada kroků, včetně logických operací a bitových posunů (tedy vlastně celá SSE2). Tyto operace jsou popsány v komentářích, ovšem ještě lepší je porovnání těchto komentářů s mezivýsledky, což si ukážeme pod zdrojovým kódem:
[bits 32]
%include "linux_macros.asm"
;-----------------------------------------------------------------------------
section .data
hex_message:
times 8 db '?'
db ' '
hex_message_length equ $ - hex_message
align 16
sse_val_1 db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
sse_val_2 db 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
;-----------------------------------------------------------------------------
section .bss
sse_tmp resb 16
;-----------------------------------------------------------------------------
section .text
global _start ; tento symbol ma byt dostupny i linkeru
_start:
mov ebx, sse_val_1 ; adresa prvniho vektoru
movdqu xmm2, [ebx] ; nacteni puvodniho vektoru do registru XMM2
print_sse_reg_as_hex xmm2 ; tisk hodnoty registru XMM2
mov ebx, sse_val_2 ; adresa druheho vektoru
movdqu xmm1, [ebx] ; nacteni puvodniho vektoru do registru XMM1
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
movdqa xmm3, xmm2 ; kopie prvniho vektoru
movdqa xmm0, xmm1 ; kopie druheho vektor
punpcklbw xmm3, xmm2 ; provedeni operace prolozeni hodnot z obou vektoru po bajtech
punpcklbw xmm0, xmm1
punpckhbw xmm2, xmm2 ; dtto
punpckhbw xmm1, xmm1
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
print_sse_reg_as_hex xmm2 ; tisk hodnoty registru XMM2
print_sse_reg_as_hex xmm3 ; tisk hodnoty registru XMM3
pmullw xmm0, xmm3 ; součiny odpovídajících si prvku
pmullw xmm1, xmm2
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
mov eax, 0x00ff00ff ; 32bitová maska sudých bajtů
movd xmm2, eax
print_sse_reg_as_hex xmm2 ; tisk hodnoty registru XMM2
pshufd xmm2, xmm2, 0 ; rozkopírování masky do všech dvouslov vektoru
print_sse_reg_as_hex xmm2 ; tisk hodnoty registru XMM2
pand xmm0, xmm2 ; vymaskování sudých bajtů
pand xmm1, xmm2 ; vymaskování sudých bajtů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
print_sse_reg_as_hex xmm1 ; tisk hodnoty registru XMM1
packuswb xmm0, xmm1 ; proložení prvků vektorů
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
movdqa xmm1, xmm0
psrldq xmm1, 8 ; bitový posun doleva
paddb xmm0, xmm1
pxor xmm1, xmm1 ; toto je taktéž proložení
psadbw xmm0, xmm1 ; součet
print_sse_reg_as_hex xmm0 ; tisk hodnoty registru XMM0
movd eax, xmm0 ; výsledná hodnota do registru EAX
print_hex eax, "*"
exit ; ukonceni procesu
%include "hex2string.asm"
100F0E0D 0C0B0A09 08070605 04030201 ; první vstupní vektor 01020304 05060708 090A0B0C 0D0E0F10 ; druhý vstupní vektor 09090A0A 0B0B0C0C 0D0D0E0E 0F0F1010 ; registr XMM0 po proložení prvků vstupních vektorů 01010202 03030404 05050606 07070808 ; registr XMM1 po proložení prvků vstupních vektorů 10100F0F 0E0E0D0D 0C0C0B0B 0A0A0909 ; registr XMM2 po proložení prvků vstupních vektorů 08080707 06060505 04040303 02020101 ; registr XMM3 po proložení prvků vstupních vektorů 90488C46 8442783C 6834542A 3C1E2010 ; 16bitové součiny odpovídajících si prvků XMM0 a XMM3 20103C1E 542A6834 783C8442 8C469048 ; 16bitové součiny odpovídajících si prvků XMM1 a XMM2 00000000 00000000 00000000 00FF00FF ; 32bitová maska sudých bajtů 00FF00FF 00FF00FF 00FF00FF 00FF00FF ; rozkopírování masky do všech dvouslov vektoru 00480046 0042003C 0034002A 001E0010 ; vymaskování sudých bajtů výsledků součinů 0010001E 002A0034 003C0042 00460048 ; vymaskování sudých bajtů výsledků součinů 101E2A34 3C424648 4846423C 342A1E10 ; proložení prvků 00000000 00000198 00000000 00000330 ; součet slov se saturací 00000330* ; výsledná hodnota vypsaná v hexadecimálním tvaru
Ověřme si výsledek ručním výpočtem:
1*16 + 2*15 + 3*14 + 4*13 + 5*12 + 6*11 + 7*10 + 8*9 + 9*8 + 10*7 + 11*6 + 12*5 + 13*4 + 14*3 + 15*2 + 16*1 = 816
A skutečně: 0×330 = 816 decimálně.
18. Závěr
Instrukční sada SSE2 nepochybně znamenala dosti velký pokrok v oblasti vektorových (SIMD) instrukcí pro platformu x86. S jejím využitím bylo (a je) možné zpracovávat vektory s různými typy prvků, na rozdíl od SSE zaměřené pouze na typ float. Taktéž je důležité, že SSE2 již není v případě 64bitové platformy x86–64 volitelným rozšířením, ale naopak povinnou součástí instrukční sady (navíc s dvojnásobným počtem pracovních registrů). To znamená, že na 64bitových systémech není nutné dodávat kód s rozhodnutím, zda SSE2 použít či nikoli. Ovšem SSE2 mělo i několik nedostatků. Ty se týkaly mj. malých (nebo spíš neohrabaných) možností extrakce dat z vektorů a jejich prokládání. Taktéž by se hodilo využívat vektory delší než 128 bitů – to plyne z toho, že počet tranzistorů na CPU neustále rostl a bylo je tak možné využívat nějakým rozumným způsobem.
Řešením (i když částečným a dočasným) se stalo rozšíření instrukční sady nazvané „Advanced Vector Extension“ neboli zkráceně pouze AVX. Oproti již popsaným rozšířením MMX či SSE a SSE2 se jedná o výrazné vylepšení podpory SIMD operací, které se mj. projevilo prodloužením vektorů a zcela novými instrukcemi, takže slovo „advanced“ je zde do jisté míry namístě. Původní technologie AVX byla představena v roce 2008, přičemž první mikroprocesory vybavené tímto rozšířením začaly být ve větších sériích prodávány v roce 2011 (na jejich adaptaci jsme tedy měli zhruba patnáct let). Jedná se tedy o (z pohledu vývojáře) relativně dobře zavedenou technologii, která je v samotném hardware dnes již široce podporována a lze ji bez větších problémů začít využívat. A právě touto technologií se budeme zabývat v navazujícím článku.
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_movsb_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_movsb_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_movsb_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_mode286.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_mode386.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 |
| 218 | mmx_paddx_saturation.asm | součet osmiprvkových a čtyřprvkových vektorů se saturací | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_paddx_saturation.asm |
| 219 | mmx_psubx.asm | rozdíl vektorů s různým počtem a šířkou prvků | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_psubx.asm |
| 220 | mmx_pmullw1.asm | součin vektorů prvek po prvku se získáním spodních 16 bitů výsledků (varianta bez přetečení) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pmullw1.asm |
| 221 | mmx_pmullw2.asm | součin vektorů prvek po prvku se získáním spodních 16 bitů výsledků (varianta s přetečením) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pmullw2.asm |
| 222 | mmx_pmulhw.asm | součin vektorů prvek po prvku se získáním horních 16 bitů výsledků (varianta s přetečením) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pmulhw.asm |
| 223 | mmx_pmaddwd.asm | součin vektorů prvek po prvku, součet mezivýsledků | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pmaddwd.asm |
| 224 | mmx_logical.asm | logické instrukce MMX | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_logical.asm |
| 225 | mmx_shift_left.asm | logické posuny prvků vektorů doleva | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_shift_left.asm |
| 226 | mmx_shift_right.asm | logické posuny prvků vektorů doprava | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_shift_right.asm |
| 227 | mmx_arithmetic_right.asm | aritmetické posuny prvků vektorů doprava | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_arithmetic_right.asm |
| 228 | mmx_cmpeq.asm | porovnání prvků vektorů na rovnost | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_cmpeq.asm |
| 229 | mmx_cmpgt.asm | porovnání prvků vektorů na relaci „větší než“ | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_cmpgt.asm |
| 230 | mmx_unpack_bytes.asm | rozbalení bajtů z vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_unpack_bytes.asm |
| 231 | mmx_unpack_words.asm | rozbalení slov z vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_unpack_words.asm |
| 232 | mmx_unpack_dwords.asm | rozbalení dvojslov z vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_unpack_dwords.asm |
| 233 | mmx_pack_into_bytes1.asm | zabalení vektorů slov do vektoru bajtů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pack_into_bytes1.asm |
| 234 | mmx_pack_into_bytes2.asm | řešení přetečení při zabalování vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/mmx_pack_into_bytes2.asm |
| 235 | sse_support.asm | detekce, zda mikroprocesor podporuje instrukce SSE | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_support.asm |
| 236 | sse_instr_formats.asm | instrukční formát SSE | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_instr_formats.asm |
| 237 | sse_value_unaligned1.asm | načtení konstanty do XMM registru (nezarovnaná adresa) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_value_unaligned1.asm |
| 238 | sse_value_unaligned2.asm | načtení konstanty do XMM registru (nezarovnaná adresa, ovšem vyžadováno je zarovnání) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_value_unaligned2.asm |
| 239 | sse_value_aligned.asm | načtení konstanty do XMM registru (zarovnaná adresa) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_value_aligned.asm |
| 240 | sse_addss.asm | skalární součet instrukcí ADDSS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_addss.asm |
| 241 | sse_addps.asm | vektorový součet instrukcí ADDPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_addps.asm |
| 242 | sse_subss.asm | skalární rozdíl instrukcí SUBSS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_subss.asm |
| 243 | sse_subps.asm | skalární rozdíl instrukcí SUBPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_subps.asm |
| 244 | sse_mulps.asm | součin prvků vektorů instrukcí MULPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_mulps.asm |
| 245 | sse_divps.asm | podíl prvků vektorů instrukcí DIVPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_divps.asm |
| 246 | sse_maxmin.asm | porovnání a výběr větších resp. menších prvků z dvojice vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_maxmin.asm |
| 247 | sse_reciprocal.asm | přibližný výpočet převrácené hodnoty | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_reciprocal.asm |
| 248 | sse_sqrt.asm | výpočet druhé odmocniny prvků | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_sqrt.asm |
| 249 | sse_cmpeqps.asm | porovnání prvků vektorů na rovnost | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cmpeqps.asm |
| 250 | sse_cmpltps.asm | porovnání prvků vektorů na relaci „menší než“ | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cmpltps.asm |
| 251 | sse_inf_nan.asm | speciální hodnoty nekonečno a NaN v instrukčním souboru SSE | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_inf_nan.asm |
| 252 | sse_ordered.asm | zjištění, které prvky vektorů jsou porovnatelné | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_ordered.asm |
| 253 | sse_unpckhps.asm | proložení prvků dvou vektorů instrukcí UNPCKHPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_unpckhps.asm |
| 254 | sse_unpcklps.asm | proložení prvků dvou vektorů instrukcí UNPCKLPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_unpcklps.asm |
| 255 | sse_shufps.asm | použití instrukce SHUFPS | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_shufps.asm |
| 256 | sse_cvtsi2ss.asm | konverze celého čísla na hodnotu typu single | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cvtsi2ss.asm |
| 257 | sse_cvtss2si.asm | konverze hodnoty typu single na celé číslo | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cvtss2si.asm |
| 258 | sse_cvtss2si_fract.asm | konverze neceločíselných hodnot na celé číslo | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cvtss2si_fract.asm |
| 258 | sse_cvtss2si_special.asm | konverze speciálních hodnot na celé číslo | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_cvtss2si_special.asm |
| 259 | sse_ldmxcsr.asm | načtení nové hodnoty do stavového a řídicího registru MXCSR z paměti | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_ldmxcsr.asm |
| 260 | sse_stmxcsr.asm | uložení hodnoty stavového a řídicího registru MXCSR do paměti | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse_stmxcsr.asm |
| 261 | sse2_support.asm | detekce podpory instrukcí SSE2 | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_support.asm |
| 262 | sse2_paddb.asm | součet dvojice vektorů 16×8 bitů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_paddb.asm |
| 263 | sse2_paddw.asm | součet dvojice vektorů 8×16 bitů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_paddw.asm |
| 264 | sse2_paddsb.asm | součet bezznaménkových bajtů se saturací | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_paddsb.asm |
| 265 | sse2_paddusb.asm | součet bajtů se znaménkem se saturací | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_paddusb.asm |
| 266 | sse2_sqrtpd.asm | výpočet druhé odmocniny vektorů s prvky typu double | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_sqrtpd.asm |
| 267 | sse2_sqrtpd_negative.asm | výpočet druhé odmocniny záporných hodnot | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_sqrtpd_negative.asm |
| 268 | sse2_sqrtpd_special.asm | výpočet druhé odmocniny nekonečen a NaN | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_sqrtpd_special.asm |
| 269 | sse2_shift_right_words.asm | bitový posun 128bitového vektoru, omezení prvků na 16bitová slova | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_shift_right_words.asm |
| 270 | sse2_shift_right_dwords.asm | bitový posun 128bitového vektoru, omezení prvků na 32bitová slova | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_shift_right_dwords.asm |
| 271 | sse2_shift_right_qwords.asm | bitový posun 128bitového vektoru, omezení prvků na 64bitová slova | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_shift_right_qwords.asm |
| 272 | sse2_shift_right_dqwords.asm | posun 128bitového vektoru po celých bajtech | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_shift_right_dqwords.asm |
| 273 | sse2_and.asm | tři varianty instrukce bitového součinu | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_and.asm |
| 274 | sse2_and_not.asm | dvě varianty instrukce bitového součinu s negací | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_and_not.asm |
| 275 | sse2_cvtps2dq.asm | konverzní instrukce CVTPS2DQ | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_cvtps2dq.asm |
| 276 | sse2_cvtps2dq_neg.asm | konverze záporných hodnot na celá čísla | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_cvtps2dq_neg.asm |
| 277 | sse2_cvtps2dq_special.asm | konverze speciálních hodnot na celá čísla | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_cvtps2dq_special.asm |
| 278 | sse2_cvtps2pd.asm | konverze vektoru s prvky typu single na prvky typu double | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_cvtps2pd.asm |
| 279 | sse2_cvtpd2ps.asm | konverze vektoru s prvky typu double na prvky typu single | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_cvtpd2ps.asm |
| 280 | sse2_cvtpd2ps_special.asm | konverze vektoru s prvky typu double na prvky typu single (speciální hodnoty) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_cvtpd2ps_special.asm |
| 281 | sse2_add_delta.asm | přičtení konstanty ke všem prvků pole (vektoru) | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_add_delta.asm |
| 282 | sse2_pmovmskb.asm | přečtení příznaku záporné hodnoty pro všechny bajty ve 128bitovém vektoru | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_pmovmskb.asm |
| 283 | sse2_unpckhpd.asm | extrakce a proložení prvků o šířce 64bitů ze 128bitových vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_unpckhpd.asm |
| 284 | sse2_unpcklpd.asm | extrakce a proložení prvků o šířce 64bitů ze 128bitových vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_unpcklpd.asm |
| 285 | sse2_punpckhbw.asm | extrakce a proložení jednotlivých bajtů ze 128bitových vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_punpckhbw.asm |
| 286 | sse2_punpcklbw.asm | extrakce a proložení jednotlivých bajtů ze 128bitových vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_punpcklbw.asm |
| 287 | sse2_pshufd.asm | komplikovanější proložení prvků vektorů instrukcí PSHUFD | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_pshufd.asm |
| 288 | sse2_add_delta.asm | přičtení konstanty ke všem bajtům ve 128bitovém vektoru | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_add_delta.asm |
| 289 | sse2_add_delta_32bytes.asm | rozšíření předchozího příkladu na dvojici 128bitových vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_add_delta_32bytes.asm |
| 290 | sse2_dot_product_16bytes.asm | skalární součin osmibitových hodnot uložených ve dvojici 128bitových vektorů | https://github.com/tisnik/8bit-fame/blob/master/pc-linux/sse2_dot_product_16bytes.asm |
20. Odkazy na Internetu
- The Intel 8088 Architecture and Instruction Set
https://people.ece.ubc.ca/~edc/464/lectures/lec4.pdf - x86 Opcode Structure and Instruction Overview
https://pnx.tf/files/x86_opcode_structure_and_instruction_overview.pdf - x86 instruction listings (Wikipedia)
https://en.wikipedia.org/wiki/X86_instruction_listings - x86 assembly language (Wikipedia)
https://en.wikipedia.org/wiki/X86_assembly_language - Intel Assembler (Cheat sheet)
http://www.jegerlehner.ch/intel/IntelCodeTable.pdf - 25 Microchips That Shook the World
https://spectrum.ieee.org/tech-history/silicon-revolution/25-microchips-that-shook-the-world - Chip Hall of Fame: MOS Technology 6502 Microprocessor
https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-mos-technology-6502-microprocessor - Chip Hall of Fame: Intel 8088 Microprocessor
https://spectrum.ieee.org/tech-history/silicon-revolution/chip-hall-of-fame-intel-8088-microprocessor - Jak se zrodil procesor?
https://www.root.cz/clanky/jak-se-zrodil-procesor/ - Apple II History Home
http://apple2history.org/ - The 8086/8088 Primer
https://www.stevemorse.org/8086/index.html - flat assembler: Assembly language resources
https://flatassembler.net/ - FASM na Wikipedii
https://en.wikipedia.org/wiki/FASM - Fresh IDE FASM inside
https://fresh.flatassembler.net/ - MS-DOS Version 4.0 Programmer's Reference
https://www.pcjs.org/documents/books/mspl13/msdos/dosref40/ - DOS API (Wikipedia)
https://en.wikipedia.org/wiki/DOS_API - Bit banging
https://en.wikipedia.org/wiki/Bit_banging - IBM Basic assembly language and successors (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Basic_assembly_language_and_successors - X86 Assembly/Bootloaders
https://en.wikibooks.org/wiki/X86_Assembly/Bootloaders - Počátky grafiky na PC: grafické karty CGA a Hercules
https://www.root.cz/clanky/pocatky-grafiky-na-pc-graficke-karty-cga-a-hercules/ - 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/ - Karta EGA: první použitelná barevná grafika na PC
https://www.root.cz/clanky/karta-ega-prvni-pouzitelna-barevna-grafika-na-pc/ - RGB Classic Games
https://www.classicdosgames.com/ - Turbo Assembler (Wikipedia)
https://en.wikipedia.org/wiki/Turbo_Assembler - Microsoft Macro Assembler
https://en.wikipedia.org/wiki/Microsoft_Macro_Assembler - IBM Personal Computer (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Personal_Computer - Intel 8251
https://en.wikipedia.org/wiki/Intel_8251 - Intel 8253
https://en.wikipedia.org/wiki/Intel_8253 - Intel 8255
https://en.wikipedia.org/wiki/Intel_8255 - Intel 8257
https://en.wikipedia.org/wiki/Intel_8257 - Intel 8259
https://en.wikipedia.org/wiki/Intel_8259 - Support/peripheral/other chips – 6800 family
http://www.cpu-world.com/Support/6800.html - Motorola 6845
http://en.wikipedia.org/wiki/Motorola_6845 - The 6845 Cathode Ray Tube Controller (CRTC)
http://www.tinyvga.com/6845 - CRTC operation
http://www.6502.org/users/andre/hwinfo/crtc/crtc.html - The 6845 Cathode Ray Tube Controller (CRTC)
http://www.tinyvga.com/6845 - Motorola 6845 and bitwise graphics
https://retrocomputing.stackexchange.com/questions/10996/motorola-6845-and-bitwise-graphics - IBM Monochrome Display Adapter
http://en.wikipedia.org/wiki/Monochrome_Display_Adapter - Color Graphics Adapter
http://en.wikipedia.org/wiki/Color_Graphics_Adapter - Color Graphics Adapter and the Brown color in IBM 5153 Color Display
https://www.aceinnova.com/en/electronics/cga-and-the-brown-color-in-ibm-5153-color-display/ - The Modern Retrocomputer: An Arduino Driven 6845 CRT Controller
https://hackaday.com/2017/05/14/the-modern-retrocomputer-an-arduino-driven-6845-crt-controller/ - flat assembler: Assembly language resources
https://flatassembler.net/ - FASM na Wikipedii
https://en.wikipedia.org/wiki/FASM - Fresh IDE FASM inside
https://fresh.flatassembler.net/ - MS-DOS Version 4.0 Programmer's Reference
https://www.pcjs.org/documents/books/mspl13/msdos/dosref40/ - DOS API (Wikipedia)
https://en.wikipedia.org/wiki/DOS_API - IBM Basic assembly language and successors (Wikipedia)
https://en.wikipedia.org/wiki/IBM_Basic_assembly_language_and_successors - X86 Assembly/Arithmetic
https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic - Art of Assembly – Arithmetic Instructions
http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter6/CH06–2.html - ASM Flags
http://www.cavestory.org/guides/csasm/guide/asm_flags.html - Status Register
https://en.wikipedia.org/wiki/Status_register - Linux assemblers: A comparison of GAS and NASM
http://www.ibm.com/developerworks/library/l-gas-nasm/index.html - Programovani v assembleru na OS Linux
http://www.cs.vsb.cz/grygarek/asm/asmlinux.html - Is it worthwhile to learn x86 assembly language today?
https://www.quora.com/Is-it-worthwhile-to-learn-x86-assembly-language-today?share=1 - Why Learn Assembly Language?
http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language - Is Assembly still relevant?
http://programmers.stackexchange.com/questions/95836/is-assembly-still-relevant - Why Learning Assembly Language Is Still a Good Idea
http://www.onlamp.com/pub/a/onlamp/2004/05/06/writegreatcode.html - Assembly language today
http://beust.com/weblog/2004/06/23/assembly-language-today/ - Assembler: Význam assembleru dnes
http://www.builder.cz/rubriky/assembler/vyznam-assembleru-dnes-155960cz - Programming from the Ground Up Book – Summary
http://savannah.nongnu.org/projects/pgubook/ - DOSBox
https://www.dosbox.com/ - The C Programming Language
https://en.wikipedia.org/wiki/The_C_Programming_Language - Hercules Graphics Card (HCG)
https://en.wikipedia.org/wiki/Hercules_Graphics_Card - Complete 8086 instruction set
https://content.ctcd.edu/courses/cosc2325/m22/docs/emu8086ins.pdf - Complete 8086 instruction set
https://yassinebridi.github.io/asm-docs/8086_instruction_set.html - 8088 MPH by Hornet + CRTC + DESiRE (final version)
https://www.youtube.com/watch?v=hNRO7lno_DM - Area 5150 by CRTC & Hornet (Party Version) / IBM PC+CGA Demo, Hardware Capture
https://www.youtube.com/watch?v=fWDxdoRTZPc - 80×86 Integer Instruction Set Timings (8088 – Pentium)
http://aturing.umcs.maine.edu/~meadow/courses/cos335/80×86-Integer-Instruction-Set-Clocks.pdf - Colour Graphics Adapter: Notes
https://www.seasip.info/VintagePC/cga.html - Restoring A Vintage CGA Card With Homebrew HASL
https://hackaday.com/2024/06/12/restoring-a-vintage-cga-card-with-homebrew-hasl/ - Demoing An 8088
https://hackaday.com/2015/04/10/demoing-an-8088/ - Video Memory Layouts
http://www.techhelpmanual.com/89-video_memory_layouts.html - Screen Attributes
http://www.techhelpmanual.com/87-screen_attributes.html - IBM PC Family – BIOS Video Modes
https://www.minuszerodegrees.net/video/bios_video_modes.htm - EGA Functions
https://cosmodoc.org/topics/ega-functions/#the-hierarchy-of-the-ega - 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/ - How 16 colors saved PC gaming – the story of EGA graphics
https://www.custompc.com/retro-tech/ega-graphics - List of 16-bit computer color palettes
https://en.wikipedia.org/wiki/List_of16-bit_computer_color_palettes - Why were those colors chosen to be the default palette for 256-color VGA?
https://retrocomputing.stackexchange.com/questions/27994/why-were-those-colors-chosen-to-be-the-default-palette-for-256-color-vga - VGA Color Palettes
https://www.fountainware.com/EXPL/vga_color_palettes.htm - Hardware Level VGA and SVGA Video Programming Information Page
http://www.osdever.net/FreeVGA/vga/vga.htm - Hardware Level VGA and SVGA Video Programming Information Page – sequencer
http://www.osdever.net/FreeVGA/vga/seqreg.htm - VGA Basics
http://www.brackeen.com/vga/basics.html - Introduction to VGA Mode ‚X‘
https://web.archive.org/web/20160414072210/http://fly.srk.fer.hr/GDM/articles/vgamodex/vgamx1.html - VGA Mode-X
https://web.archive.org/web/20070123192523/http://www.gamedev.net/reference/articles/article356.asp - Mode-X: 256-Color VGA Magic
https://downloads.gamedev.net/pdf/gpbb/gpbb47.pdf - Instruction Format in 8086 Microprocessor
https://www.includehelp.com/embedded-system/instruction-format-in-8086-microprocessor.aspx - How to use „AND,“ „OR,“ and „XOR“ modes for VGA Drawing
https://retrocomputing.stackexchange.com/questions/21936/how-to-use-and-or-and-xor-modes-for-vga-drawing - VGA Hardware
https://wiki.osdev.org/VGA_Hardware - Programmer's Guide to Yamaha YMF 262/OPL3 FM Music Synthesizer
https://moddingwiki.shikadi.net/wiki/OPL_chip - Does anybody understand how OPL2 percussion mode works?
https://forum.vcfed.org/index.php?threads/does-anybody-understand-how-opl2-percussion-mode-works.60925/ - Yamaha YMF262 OPL3 music – MoonDriver for OPL3 DEMO [Oscilloscope View]
https://www.youtube.com/watch?v=a7I-QmrkAak - Yamaha OPL vs OPL2 vs OPL3 comparison
https://www.youtube.com/watch?v=5knetge5Gs0 - OPL3 Music Crockett's Theme
https://www.youtube.com/watch?v=HXS008pkgSQ - Bad Apple (Adlib Tracker – OPL3)
https://www.youtube.com/watch?v=2lEPH6Y3Luo - FM Synthesis Chips, Codecs and DACs
https://www.dosdays.co.uk/topics/fm_synthesizers.php - The Zen Challenge – YMF262 OPL3 Original (For an upcoming game)
https://www.youtube.com/watch?v=6JlFIFz1CFY - [adlib tracker II techno music – opl3] orbit around alpha andromedae I
https://www.youtube.com/watch?v=YqxJCu_WFuA - [adlib tracker 2 music – opl3 techno] hybridisation process on procyon-ii
https://www.youtube.com/watch?v=daSV5mN0sJ4 - Hyper Duel – Black Rain (YMF262 OPL3 Cover)
https://www.youtube.com/watch?v=pu_mzRRq8Ho - IBM 5155–5160 Technical Reference
https://www.minuszerodegrees.net/manuals/IBM/IBM_5155_5160_Technical_Reference_6280089_MAR86.pdf - a ymf262/opl3+pc speaker thing i made
https://www.youtube.com/watch?v=E-Mx0lEmnZ0 - [OPL3] Like a Thunder
https://www.youtube.com/watch?v=MHf06AGr8SU - (PC SPEAKER) bad apple
https://www.youtube.com/watch?v=LezmKIIHyUg - Powering devices from PC parallel port
http://www.epanorama.net/circuits/lptpower.html - Magic Mushroom (demo pro PC s DOSem)
http://www.crossfire-designs.de/download/articles/soundcards//mushroom.rar - Píseň Magic Mushroom – originál
http://www.crossfire-designs.de/download/articles/soundcards/speaker_mushroom_converted.mp3 - Píseň Magic Mushroom – hráno na PC Speakeru
http://www.crossfire-designs.de/download/articles/soundcards/speaker_mushroom_speaker.mp3 - Pulse Width Modulation (PWM) Simulation Example
http://decibel.ni.com/content/docs/DOC-4599 - Resistor/Pulse Width Modulation DAC
http://www.k9spud.com/traxmod/pwmdac.php - Class D Amplifier
http://en.wikipedia.org/wiki/Electronic_amplifier#Class_D - Covox Speech Thing / Disney Sound Source (1986)
http://www.crossfire-designs.de/index.php?lang=en&what=articles&name=showarticle.htm&article=soundcards/&page=5 - Covox Digital-Analog Converter (Rusky, obsahuje schémata)
http://phantom.sannata.ru/konkurs/netskater002.shtml - PC-GPE on the Web
http://bespin.org/~qz/pc-gpe/ - Keyboard Synthesizer
http://www.solarnavigator.net/music/instruments/keyboards.htm - FMS – Fully Modular Synthesizer
http://fmsynth.sourceforge.net/ - Javasynth
http://javasynth.sourceforge.net/ - Software Sound Synthesis & Music Composition Packages
http://www.linux-sound.org/swss.html - Mx44.1 Download Page (software synthesizer for linux)
http://hem.passagen.se/ja_linux/ - Software synthesizer
http://en.wikipedia.org/wiki/Software_synthesizer - Frequency modulation synthesis
http://en.wikipedia.org/wiki/Frequency_modulation_synthesis - Yamaha DX7
http://en.wikipedia.org/wiki/Yamaha_DX7 - Wave of the Future
http://www.wired.com/wired/archive/2.03/waveguides_pr.html - Analog synthesizer
http://en.wikipedia.org/wiki/Analog_synthesizer - Minimoog
http://en.wikipedia.org/wiki/Minimoog - Moog synthesizer
http://en.wikipedia.org/wiki/Moog_synthesizer - Tutorial for Frequency Modulation Synthesis
http://www.sfu.ca/~truax/fmtut.html - An Introduction To FM
http://ccrma.stanford.edu/software/snd/snd/fm.html - John Chowning
http://en.wikipedia.org/wiki/John_Chowning - I'm Impressed, Adlib Music is AMAZING!
https://www.youtube.com/watch?v=PJNjQYp1ras - Milinda- Diode Milliampere ( OPL3 )
https://www.youtube.com/watch?v=oNhazT5HG0E - Dune 2 – Roland MT-32 Soundtrack
https://www.youtube.com/watch?v=kQADZeB-z8M - Interrupts
https://wiki.osdev.org/Interrupts#Types_of_Interrupts - Assembly8086SoundBlasterDmaSingleCycleMode
https://github.com/leonardo-ono/Assembly8086SoundBlasterDmaSingleCycleMode/blob/master/sbsc.asm - Interrupts in 8086 microprocessor
https://www.geeksforgeeks.org/interrupts-in-8086-microprocessor/ - Interrupt Structure of 8086
https://www.eeeguide.com/interrupt-structure-of-8086/ - A20 line
https://en.wikipedia.org/wiki/A20_line - Extended memory
https://en.wikipedia.org/wiki/Extended_memory#eXtended_Memory_Specification_(XMS) - Expanded memory
https://en.wikipedia.org/wiki/Expanded_memory - Protected mode
https://en.wikipedia.org/wiki/Protected_mode - Virtual 8086 mode
https://en.wikipedia.org/wiki/Virtual_8086_mode - Unreal mode
https://en.wikipedia.org/wiki/Unreal_mode - DOS memory management
https://en.wikipedia.org/wiki/DOS_memory_management - Upper memory area
https://en.wikipedia.org/wiki/Upper_memory_area - Removing the Mystery from SEGMENT : OFFSET Addressing
https://thestarman.pcministry.com/asm/debug/Segments.html - Segment descriptor
https://en.wikipedia.org/wiki/Segment_descriptor - 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/questions/45094696/when-using-a-32-bit-register-to-address-memory-in-the-real-mode-contents-of-the - A Brief History of Unreal Mode
https://www.os2museum.com/wp/a-brief-history-of-unreal-mode/ - Segment Limits
https://wiki.osdev.org/Segment_Limits - How do 32 bit addresses in real mode work?
https://forum.osdev.org/viewtopic.php?t=30642 - The LOADALL Instruction by Robert Collins
https://www.rcollins.org/articles/loadall/tspec_a3_doc.html - How do you put a 286 in Protected Mode?
https://retrocomputing.stackexchange.com/questions/7683/how-do-you-put-a-286-in-protected-mode - Control register
https://en.wikipedia.org/wiki/Control_register - CPU Registers x86
https://wiki.osdev.org/CPU_Registers_x86 - x86 Assembly/Protected Mode
https://en.wikibooks.org/wiki/X86_Assembly/Protected_Mode - MSW: Machine Status Word
https://web.itu.edu.tr/kesgin/mul06/intel/intel_msw.html - 80×87 Floating Point Opcodes
http://www.techhelpmanual.com/876–80×87_floating_point_opcodes.html - Page Translation
https://pdos.csail.mit.edu/6.828/2005/readings/i386/s05_02.htm - 80386 Paging and Segmenation
https://stackoverflow.com/questions/38229741/80386-paging-and-segmenation - 80386 Memory Management
https://tldp.org/LDP/khg/HyperNews/get/memory/80386mm.html - DOSEMU
http://www.dosemu.org/ - Intel 80386, a revolutionary CPU
https://www.xtof.info/intel80386.html - PAI Unit 3 Paging in 80386 Microporcessor
https://www.slideshare.net/KanchanPatil34/pai-unit-3-paging-in-80386-microporcessor - 64 Terabytes of virtual memory for 32-bit x86 using segmentation: how?
https://stackoverflow.com/questions/5444984/64-terabytes-of-virtual-memory-for-32-bit-x86-using-segmentation-how - Pi in the Pentium: reverse-engineering the constants in its floating-point unit
http://www.righto.com/2025/01/pentium-floating-point-ROM.html - Simply FPU
http://www.website.masmforum.com/tutorials/fptute/ - Art of Assembly language programming: The 80×87 Floating Point Coprocessors
https://courses.engr.illinois.edu/ece390/books/artofasm/CH14/CH14–3.html - Art of Assembly language programming: The FPU Instruction Set
https://courses.engr.illinois.edu/ece390/books/artofasm/CH14/CH14–4.html - INTEL 80387 PROGRAMMER'S REFERENCE MANUAL
http://www.ragestorm.net/downloads/387intel.txt - x86 Instruction Set Reference: FLD
http://x86.renejeschke.de/html/file_module_x86_id100.html - x86 Instruction Set Reference: FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ
http://x86.renejeschke.de/html/file_module_x86_id101.html - X86 Assembly/Arithmetic
https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic - 8087 Numeric Data Processor
https://www.eeeguide.com/8087-numeric-data-processor/ - Data Types and Instruction Set of 8087 co-processor
https://www.eeeguide.com/data-types-and-instruction-set-of-8087-co-processor/ - 8087 instruction set and examples
https://studylib.net/doc/5625221/8087-instruction-set-and-examples - GCC documentation: Extensions to the C Language Family
https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions - GCC documentation: Using Vector Instructions through Built-in Functions
https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html - SSE (Streaming SIMD Extentions)
http://www.songho.ca/misc/sse/sse.html - Timothy A. Chagnon: SSE and SSE2
http://www.cs.drexel.edu/~tc365/mpi-wht/sse.pdf - Intel corporation: Extending the Worldr's Most Popular Processor Architecture
http://download.intel.com/technology/architecture/new-instructions-paper.pdf - SIMD architectures:
http://arstechnica.com/old/content/2000/03/simd.ars/ - Tour of the Black Holes of Computing!: Floating Point
http://www.cs.hmc.edu/~geoff/classes/hmc.cs105…/slides/class02_floats.ppt - 3Dnow! Technology Manual
AMD Inc., 2000 - Intel MMXTM Technology Overview
Intel corporation, 1996 - MultiMedia eXtensions
http://softpixel.com/~cwright/programming/simd/mmx.phpi - AMD K5 („K5“ / „5k86“)
http://www.pcguide.com/ref/cpu/fam/g5K5-c.html - Sixth Generation Processors
http://www.pcguide.com/ref/cpu/fam/g6.htm - Great Microprocessors of the Past and Present
http://www.cpushack.com/CPU/cpu1.html - Very long instruction word (Wikipedia)
http://en.wikipedia.org/wiki/Very_long_instruction_word - CPU design (Wikipedia)
http://en.wikipedia.org/wiki/CPU_design - Bulldozer (microarchitecture)
https://en.wikipedia.org/wiki/Bulldozer_(microarchitecture) - MMX (instruction set)
https://en.wikipedia.org/wiki/MMX_(instruction_set) - Extended MMX
https://en.wikipedia.org/wiki/Extended_MMX - Saturation arithmetic
https://en.wikipedia.org/wiki/Saturation_arithmetic - CMPPS — Compare Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/cmpps - ADDPS — Add Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/addps - SUBPS — Subtract Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/subps - SQRTPS — Square Root of Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/sqrtps - RSQRTPS — Compute Reciprocals of Square Roots of Packed Single Precision Floating-PointValues
https://www.felixcloutier.com/x86/rsqrtps - UNPCKHPS — Unpack and Interleave High Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/unpckhps - UNPCKLPS — Unpack and Interleave Low Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/unpcklps - SHUFPS — Packed Interleave Shuffle of Quadruplets of Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/shufps - CVTSI2SS — Convert Doubleword Integer to Scalar Single Precision Floating-Point Value
https://www.felixcloutier.com/x86/cvtsi2ss - CVTSS2SI — Convert Scalar Single Precision Floating-Point Value to Doubleword Integer
https://www.felixcloutier.com/x86/cvtss2si - CVTTSS2SI — Convert With Truncation Scalar Single Precision Floating-Point Value to Integer
https://www.felixcloutier.com/x86/cvttss2si - CVTPI2PS — Convert Packed Dword Integers to Packed Single Precision Floating-Point Values
https://www.felixcloutier.com/x86/cvtpi2ps - CVTPS2PI — Convert Packed Single Precision Floating-Point Values to Packed Dword Integers
https://www.felixcloutier.com/x86/cvtps2pi - CVTTPS2PI — Convert With Truncation Packed Single Precision Floating-Point Values to PackedDword Integers
https://www.felixcloutier.com/x86/cvttps2pi - Streaming SIMD Extensions 2 (SSE2)
https://softpixel.com/~cwright/programming/simd/sse2.php - Redundant SSE instructions
https://www.pagetable.com/?p=19