Nedílnou součástí prakticky všech moderních mikroprocesorů i některých mikrořadičů je modul určený pro provádění operací s hodnotami s plovoucí řádovou čárkou. S některými možnostmi nabízenými tímto modulem, který se v minulosti označoval termínem „matematický koprocesor“, se ve stručnosti seznámíme v dnešním článku.

Obsah

1. Použití assembleru v Linuxu: práce s matematickým koprocesorem

2. Rozdíl mezi celočíselnými operacemi a operacemi s hodnotami s plovoucí řádovou čárkou

3. Norma IEEE 754 a její varianty

4. Způsob interní reprezentace hodnot s plovoucí řádovou čárkou

5. Formát single – hodnoty s jednoduchou přesností

6. Uložení znaménka, mantisy a exponentu ve formátu single

7. Speciální hodnoty s exponenty 0 a 255

8. Denormalizovaná čísla, hodnoty typu NaN a nekonečna

9. Formát double – hodnoty s dvojnásobnou přesností

10. Rozšířený formát extended/temporary

11. Pracovní registry matematického koprocesoru

12. Řídicí registr

13. Stavový registr

14. Základní instrukce – načítání dat do registrů

15. Aritmetické operace

16. Odkazy na Internetu

1. Použití assembleru v Linuxu: práce s matematickým koprocesorem

Na všech mikroprocesorech s architekturou i386 i x86-64 a taktéž u většiny mikroprocesorů s architekturou ARM (s výjimkou některých menších mikrořadičů řady Cortex-M či starších čipů předchozí generace) nalezneme modul, který je určený pro provádění operací s hodnotami reprezentovanými v takzvaném systému plovoucí řádové čárky. V angličtině se používá označení floating point, protože při zápisu desetinných čísel se zde používá tečka a nikoli čárka. Tento modul se z historických důvodů nazývá „matematický koprocesor“, a to proto, že v minulosti se skutečně jednalo o samostatný čip, který bylo možné na základní desku počítače nainstalovat až ve chvíli, kdy to bylo vzhledem k provozovaným úlohám nezbytné (typicky se jednalo o osobní mikropočítače, na nichž se provozoval CAD popř. se na něm v tabulkovém procesoru zpracovávaly rozsáhlejší tabulky s mnoha výpočty). Později se matematický koprocesor stal nedílnou součástí mikroprocesoru, což znamená, že dnes již není nutné testovat jeho přítomnost, provádění všech operací s plovoucí řádovou čárkou je rychlejší (sdílí se společná interní sběrnice) a taktéž není nutné explicitně čekat na dokončení výpočtů.

V dnešním článku se seznámíme především s instrukcemi i s principem práce s hodnotami s plovoucí řádovou čárkou, který je použit na mikroprocesorech s architekturou i386 a x86-64. Až příště si řekneme, jakým způsobem lze podobné výpočty provádět na čipech s architekturou ARM (tam je totiž situace poněkud složitější vzhledem k mnoha různým variantám, s nimiž se můžeme setkat).

2. Rozdíl mezi celočíselnými operacemi a operacemi s hodnotami s plovoucí řádovou čárkou

Již v úvodu je nutné upozornit na fakt, že zpracování hodnot s plovoucí řádovou čárkou se v mnoha ohledech odlišuje od zpracování celočíselných hodnot. Je tomu tak hned z několika důvodů. U celočíselných hodnot je u všech současných mikroprocesorových architektur totiž předem zřejmé, jaké hodnoty lze uložit do zvoleného n-bitového slova. Například u osmibitových slov je při použití čísel bez znaménka možné reprezentovat hodnoty od 0 do 255 (včetně), zatímco u čísel se znaménkem (konkrétně s dvojkovým doplňkem) jsou to hodnoty od -128 do 127. Navíc je při provádění základních aritmetických operací nutné sledovat pouze několik výjimečných stavů:

  1. Přenos u čísel bez znaménka (carry)
  2. Přetečení u čísel se znaménkem (overflow)
  3. Dělení nulou

Povšimněte si, že není nutné řešit například práci s nekonečnými hodnotami (kladné a záporné nekonečno), protože takové hodnoty stejně nelze nijak reprezentovat, čímž se detekce potenciálně neplatných výpočtů zjednodušuje. Není například nutné řešit, co se stane v případě pokusu o výpočet ∞-∞ nebo 0×∞, vlastně jedinou potenciálně problematickou operací je výpočet x/0 a speciálně též 0/0 (setkáme se dokonce s ALU, kde je výsledek tohoto výpočtu jednička).

Naproti tomu u hodnot reprezentovaných v systému plovoucí řádové čárky může výjimečných stavů nastat mnohem více, a to i ve chvíli, kdy uvažujeme pouze čtyři základní aritmetické operace a ne speciality typu druhá odmocnina ze záporného čísla atd.:

  1. Přetečení
  2. Podtečení
  3. Práce s tzv. denormalizovanými čísly
  4. Operace s nekonečny (kladné, záporné)
  5. Neplatné operace typu 0/0, ∞-∞ nebo 0×∞
  6. Operace s hodnotami, které nejsou skutečná čísla (NaN)

Navíc se zde objevuje další problém, který u celých čísel nebylo nutné řešit – jakým způsobem se má provádět zaokrouhlení výsledků tak, aby je bylo možné uložit zpět do pracovních registrů.

3. Norma IEEE 754 a její varianty

Před popisem jednotlivých instrukcí určených pro provádění operací s hodnotami s plovoucí řádovou čárkou je nutné se seznámit s tím, jak jsou vlastně taková čísla interně reprezentována (tj. uložena v pracovních registrech či v operační paměti), protože způsob jejich reprezentace do značné míry určuje i přesnost, rozsah podporovaných hodnot, některá specifika (způsob porovnávání) apod. U naprosté většiny polovodičových čipů vyrobených v posledním čtvrtstoletí se pro reprezentaci numerických hodnot s plovoucí řádovou čárkou dodržují vybrané formáty (někdy i všechny formáty!) specifikované v normě IEEE 754, která sama je postupně rozšiřována a upřesňována. V normě IEEE 754, jejíž první verze je mimochodem v platnosti již od roku 1985, jsou specifikovány nejenom vlastní formáty uložení numerických hodnot v systému pohyblivé řádové čárky (FP formátu), ale i pravidla implementace základních aritmetických operací s těmito hodnotami, aplikace zaokrouhlovacích režimů, způsoby některých konverzí apod. Konkrétně je v této normě popsáno:

  1. Základní (basic) a rozšířený (extended) formát uložení numerických hodnot.
  2. Způsob provádění základních matematických operací:
    • součet
    • rozdíl
    • součin
    • podíl
    • zbytek po dělení
    • druhá odmocnina
    • porovnání
  3. Režimy zaokrouhlování.
  4. Způsob práce s denormalizovanými hodnotami.
  5. Pravidla konverze mezi celočíselnými formáty (integer bez a se znaménkem) a formáty s plovoucí řádovou čárkou.
  6. Způsob konverze mezi různými formáty s plovoucí řádovou čárkou (singledouble atd.).
  7. Způsob konverze základního formátu s plovoucí řádovou čárkou na řetězec číslic (včetně nekonečen a nečíselných hodnot).
  8. Práce s hodnotami NaN (not a number) a výjimkami, které mohou při výpočtech za určitých předpokladů vzniknout.

4. Způsob interní reprezentace hodnot s plovoucí řádovou čárkou

Vybraná podmnožina racionálních čísel může být vyjádřena vztahem:

XFP=(-1)s × 2exp-bias × m

přičemž význam jednotlivých symbolů ve vztahu je následující:

  • XFP značí reprezentovanou numerickou hodnotu z podmnožiny racionálních čísel (ta je zase podmnožinou čísel reálných). Díky vyhrazeným (speciálním) hodnotám je možné rozlišit kladnou a zápornou nulu i kladné a záporné nekonečno, což je jeden z důležitých rozdílů oproti způsobu reprezentace celých čísel. Také se může uložit nečíselná hodnota: NaN – (Not a Number), která je výsledkem některých matematicky nedefinovaných operací, například 0/0 nebo 00.
  • 2 je báze, někdy také nazývaná radix, u normy IEEE 754 je to vždy dvojka, protože výpočty s bází dvě jsou pro číslicové obvody nejjednodušší. V minulosti se používaly i jiné báze, například 8, 16 nebo i 10, s nimi se však již dnes prakticky nesetkáme.
  • exp je vždy kladná hodnota exponentu posunutého o hodnotu bias
  • bias je hodnota, díky které je uložený exponent vždy kladný. Tato hodnota se většinou volí dle vztahu: bias=2eb-1-1, kde eb je počet bitů vyhrazených pro exponent. Pro specifické účely je však možné zvolit i jinou hodnotu.
  • m je mantisa, která je u formátů dle normy IEEE 754 vždy kladná
  • s je znaménkový bit nabývající hodnoty 0 nebo 1. Pokud je tento bit nulový, je reprezentovaná hodnota XFP kladná, v opačném případě se jedná o zápornou hodnotu. Vzhledem k tomu, že je jeden bit vyhrazen na uložení znaménka, je možné rozlišit kladnou a zápornou nulu.

5. Formát single – hodnoty s jednoduchou přesností

Podle bitové šířky čísel exp, bias a m se rozlišují základní (basic) a rozšířené (extended) formáty FP čísel; norma IEEE 754 přitom explicitně zmiňuje dva základní formáty: jednoduchá přesnost (single) a dvojitá přesnost (double).

Tento formát, který je v programovacích jazycích označován buď jako single či float, je charakteristický tím, že se pro uložení numerické hodnoty používá třiceti dvou bitů (4 byty), což pro mnoho aplikací představuje velmi dobrý poměr mezi rozsahem hodnot, přesností a nároky na úložný prostor, nehledě na to, že mnoho architektur stále používá 32 bitové sběrnice. Oněch 32 bitů je rozděleno do třech částí. V první části (představované nejvyšším bitem) je uloženo znaménko, následuje osm bitů pro uložení posunutého exponentu a za nimi je zbývajících 23 bitů, které slouží pro uložení mantisy. Celé třiceti dvoubitové slovo s FP hodnotou tedy vypadá následovně:

bit3130   29 … 24   2322   21 … 3   2   1   0
významsexponent (8 bitů)mantisa (23 bitů)

Exponent je přitom posunutý o hodnotu bias, která je nastavena na 127, protože je použit výše uvedený vztah:

bias=2eb-1-1

a po dosazení eb=8 (bitů) dostaneme:

bias=28-1-1=27-1=128-1=127

Vzorec pro vyjádření reálné hodnoty vypadá následovně:

Xsingle=(-1)s × 2exp-127 × m

6. Uložení znaménka, mantisy a exponentu ve formátu single

Uložení znaménka číselné hodnoty je jednoduché: pokud je znaménkový bit nastavený na jedničku, jedná se o zápornou hodnotu, v opačném případě jde o hodnotu kladnou. Exponent je uložený v takzvané posunuté formě, tj. jako binárně zakódované celé číslo v rozsahu 0..255. Po vyjádření neposunutého exponentu dostáváme rozsah -127..128, obě krajní hodnoty jsou však použity pro speciální účely, proto dostáváme rozsah exponentů -126..127 pro normalizovaná čísla (krajními hodnotami jsou takové exponenty, které mají všechny bity buď jedničkové nebo naopak nulové). Ještě si však musíme říci, jakým způsobem je uložena mantisa. Ta je totiž většinou (až na velmi malá čísla) normalizovaná, což znamená, že se do mantisy ukládají pouze hodnoty v rozsahu <1,0;2,0-ε>. Vzhledem k tomu, že první bit umístěný před binární tečkou je u tohoto rozsahu vždy nastavený na jedničku, není ho zapotřebí ukládat, což znamená, že ušetříme jeden bit z třiceti dvoubitového slova. Pro normalizované hodnoty platí následující vztah:

Xsingle=(-1)s × 2exp-127(1.M)2

kde M je hodnota bitového vektoru mantisy, tj.:

M=m22-1+m21-2+m20-3+…+m1-22+m0-23

Rozsah hodnot, jež je možné reprezentovat pomocí jednoduché přesnosti v normalizovaném tvaru je -3,4×1038 až 3,4×1038. Nejnižší reprezentovatelná (normalizovaná) hodnota je rovna 1,17549×10-38, denormalizovaná pak 1,40129×10-45. Jak jsme k těmto hodnotám došli? Zkuste se podívat na následující vztahy:

hexadecimální hodnotavýpočet FPdekadický výsledeknormalizováno
0x000000012-126×2-231,40129×10-45ne
0x008000002-1261,17549×10-38ano
0x7F7FFFFF(2-2-23)×21273,4×1038ano

7. Speciální hodnoty s exponenty 0 a 255

Ještě si musíme vysvětlit význam těch exponentů, které mají minimální a maximální hodnotu, tj. jsou buď nulové, nebo mají hodnotu 255 (obě samozřejmě před posunem). Vše je přehledně uvedeno v následující tabulce:

s-bitexponentmantisavýznamšestnáctkově
00<e<255>0normalizované kladné číslo
10<e<255>0normalizované záporné číslo
00>0denormalizované kladné číslo
10>0denormalizované záporné číslo
000kladná nula0x00000000
100záporná nula0x80000000
02550kladné nekonečno0x7F800000
12550záporné nekonečno0xFF800000
0255>0NaN – not a number
1255>0NaN – not a number

8. Denormalizovaná čísla, hodnoty typu NaN a nekonečna

Pojmem denormalizovaná čísla označujeme takové hodnoty, u kterých není první (explicitně nevyjádřený) bit mantisy roven jedničce, ale naopak nule. Výpočty s těmito velmi malými hodnotami nejsou přesné, zejména při násobení a dělení (a samozřejmě i všech odvozených operacích). Při ukládání denormalizovaných čísel je exponent vždy nastaven na nejnižší hodnotu, tj. na -126 a nejvyšší (explicitně neukládaný) bit mantisy je vždy nulový, nikoli jedničkový, jak je tomu u normalizovaných hodnot. Hodnota typu NaN vznikne v případě, že je použita operace s nejasným výsledkem, například 0/0, 00 nebo, a to v praxi snad nejčastěji, při odmocňování záporných čísel. Nekonečná hodnota vzniká typicky při dělení nulou (zde je možné zjistit znaménko), nebo při vyjádření funkcí typu log(0) atd.

9. Formát double – hodnoty s dvojnásobnou přesností

Formát s dvojitou přesností (double), který je definovaný taktéž normou IEEE 754, se v mnoha ohledech podobá formátu s jednoduchou přesností (single), pouze se zdvojnásobil celkový počet bitů, ve kterých je hodnota uložena, tj. místo 32 bitů se používá 64 bitů. Právě to je hlavní příčinou toho, proč se tento formát nazývá double, ve skutečnosti je totiž přesnost více než dvojnásobná. 64 bitů alokovaných pro FP hodnotu je v tomto případě rozděleno následujícím způsobem:

  1. 1 bit pro znaménko
  2. 11 bitů pro exponent
  3. 52 bitů pro mantisu

Bitově vypadá rozdělení následovně:

bit6362 … 5251 … 0
významsexponent (11 bitů)mantisa 52( bitů)

Exponent je v tomto případě posunutý o hodnotu bias=2047 a vzorec pro výpočet reálné hodnoty vypadá takto:

Xdouble=(-1)s × 2exp-2047 × m

Přičemž hodnotu mantisy je možné pro normalizované hodnoty získat pomocí vztahu:

m=1+m51-1+m50-2+m49-3+…+m0-52

(mx představuje x-tý bit mantisy)

Rozsah hodnot ukládaných ve dvojité přesnosti je -1,7×10308..1,7×10308, nejmenší možná nenulová hodnota je rovna 2,2×10-308. Minimální a maximální hodnota exponentu má opět speciální význam, který je vysvětlen (spolu s normalizovanými čísly) v následující tabulce:

s-bitexponentmantisavýznam
00<e<2047>0normalizované kladné číslo
10<e<2047>0normalizované záporné číslo
00>0denormalizované kladné číslo
10>0denormalizované záporné číslo
000kladná nula
100záporná nula
020470kladné nekonečno
120470záporné nekonečno
02047>0NaN – not a number
12047>0NaN – not a number

10. Rozšířený formát extended/temporary

Kromě obou základních formátů (tj. jednoduché i dvojité přesnosti) je v normě IEEE 754 povoleno používat i rozšířené formáty. Na platformě x86 je při výpočtech prováděných v matematickém koprocesoru používán rozšířený formát nazývaný extended či temporary. Tento formát je zajímavý tím, že pro uložení FP hodnot používá 80 bitů a je do něho možné beze ztráty přesnosti uložit 64bitové hodnoty typu integer (což je v mnoha oblastech velmi důležité). Osmdesátibitový vektor je rozdělený do třech částí následujícím způsobem:

  • 1 bit pro znaménko
  • 15 bitů pro exponent (BIAS je roven 16383)
  • 64 bitů pro mantisu (maximální hodnota přesahuje 104932)

U tohoto formátu je zajímavá funkce bitu s indexem 63. Podle hodnoty tohoto bitu se rozlišují čísla normalizovaná a nenormalizovaná (tento bit ve skutečnosti nahrazuje implicitně nastavovaný nejvyšší bit mantisy, jak ho známe z předchozích formátů). Matematické koprocesory řady 80×87 sice dokážou pracovat s čísly nenormalizovanými, výsledkem jeho aritmetických operací jsou však vždy hodnoty normalizované. Všechny možnosti, které mohou při ukládání extended FP formátu nastat, jsou přehledně vypsány v následující tabulce:

s-bitexponentmantisam63význam
00<e<32767>01normalizované kladné číslo
10<e<32767>01normalizované záporné číslo
00<e<32767>00nenormalizované kladné číslo
10<e<32767>00nenormalizované záporné číslo
00>00denormalizované kladné číslo
10>00denormalizované záporné číslo
000xkladná nula
100xzáporná nula
0327670xkladné nekonečno
1327670xzáporné nekonečno
032767>0xNaN – not a number
132767>0xNaN – not a number

Pro normalizované i nenormalizované hodnoty je možné uloženou hodnotu vyjádřit pomocí vzorce (všimněte si, že bit 63 je umístěn před binární tečkou):

Xextended=(-1)s × 2exp-16383 × m

m=m630+m62-1+m61-2+…+m0-63

11. Pracovní registry matematického koprocesoru

Matematický koprocesor má k dispozici celkem osm pracovních registrů, přičemž každý registr má šířku osmdesáti bitů. To znamená, že je možné provádět operace s hodnotami s rozšířenou (extended) přesností a samozřejmě taktéž s přesností jednoduchou (single) a dvojitou (double). Zajímavé a dnes již poněkud neobvyklé je, že zmíněných osm registrů tvoří zásobník, takže instrukce pro načítání hodnot ve skutečnosti provádí uložení na vrchol zásobníku, aritmetické operace pracují se dvěma registry na vrcholu zásobníku atd. U mnoha instrukcí je však možné toto pravidlo porušit a zvolit si registry explicitně, popř. zakázat odstranění původních operandů ze zásobníku. Zápis jmen registrů vypadá takto: ST(0), ST(1) atd. (pořadí registru v zásobníku se průběžně mění). Moderní FPU již tento zásobníkový koncept, který byl výhodný pro starší a méně dobré překladače, zcela odstranily.

12. Řídicí registr

Kromě pracovních registrů obsahuje matematický koprocesor i řídicí registr (control register). Ten má šířku pouze šestnáct bitů a obsahuje masky výjimek, které mohou nastat při provádění různých operací, dále pak dva bity pro volbu zaokrouhlovacího režimu a taktéž dva bity pro volbu přesnosti jednotlivých výpočtů:

#OznačeníVýznam
0IMmaska výjimky Invalid Operation
1DMmaska výjimky Denormalized Operand
2ZMmaska výjimky Zero Divide
3OMmaska výjimky Overflow
4UMmaska výjimky Underflow
5PMmaska výjimky Precision
6×
7IEpovolení přerušení (dnes nevyužito)
8PC1volba přesnosti výpočtů (viz tabulku níže)
9PC2-//-
10RC1volba zaokrouhlovacího režimu (viz tabulku níže)
11RC2-//-
12ICdnes nepoužito, pro kompatibilitu s 80287
13×
14×
15×

Bity RC2 a RC1 se používají pro volbu zaokrouhlení:

RC2RC1
00zaokrouhlení na nejbližší sudé číslo (mantisa)
01zaokrouhlení směrem k -∞
10zaokrouhlení směrem k +∞
11zaokrouhlení směrem k nule

Bity PC2 a PC1 určují, zda se mají výpočty provádět s jednoduchou přesností, dvojitou přesností či s rozšířenou přesností:

PC2PC1
0032 bitů
01
1064 bitů
1180 bitů (výchozí)

Většinou není nutné obsah tohoto registru v průběhu výpočtů měnit.

13. Stavový registr

Jednotlivé matematické operace prováděné matematickým koprocesorem nastavují bity v takzvaném stavovém registru (status register). Tento registru má taktéž šířku šestnácti bitů a jeho struktura vypadá následovně:

#OznačeníVýznam
0IEvýjimka Invalid Operation
1DEvýjimka Denormalized Operand
2ZOvýjimka Zero Divide
3OEvýjimka Overflow
4UEvýjimka Underflow
5PEvýjimka Precision
6SFšpatná manipulace se zásobníkem operandů
7ESError summary
8C0výsledek porovnání (příznakový bit)
9C1výsledek porovnání (příznakový bit)
10C2výsledek porovnání (příznakový bit)
11ST0ukazatel vrcholu zásobníku
12ST1ukazatel vrcholu zásobníku
13ST2ukazatel vrcholu zásobníku
14C3výsledek porovnání (příznakový bit)
15Bbusy bit (provádí se operace)

Nejzajímavější jsou bity C0, C1, C2 a C3, protože do těchto bitů se ukládá například výsledek porovnání dvou hodnot atd. Tyto bity jsou ve stavovém registru umístěny tak, aby přesně odpovídaly umístění standardních příznaků v registru EFLAGS:

FPUEFLAGS
C0carry flag
C1undefined
C2parity flag
C3zero flag

Způsob použití si ukážeme příště.

14. Základní instrukce – načítání dat do registrů

V této kapitole si prozatím bez demonstračního příkladu vypíšeme základní instrukce určené pro načtení dat do registrů FPU. Jedná se o následujících osm instrukcí:

#InstrukceVýznam
1FLDnačtení hodnoty typu single, double či extended z paměti či jiného registru
2FLD1načtení konstanty +1,0
3FLDL2Tnačtení konstanty log210
4FLDL2Enačtení konstanty log2e
5FLDPInačtení konstanty π
6FLDLG2načtení konstanty log102
7FLDLN2načtení konstanty loge2
8FLDZnačtení konstanty +0,0 (kladná nula)

Hodnoty logaritmů se využijí v mnoha instrukcích, které si popíšeme příště.

15. Aritmetické operace

Mezi základní aritmetické operace patří především:

#InstrukceVýznam
1FADDsoučet
2FSUBrozdíl
3FSUBRrozdíl, ale operandy jsou prohozeny
4FMULsoučin
5FDIVpodíl
6FDIVRpodíl, ale operandy jsou prohozeny
7FCHSzměna znaménka
8FABSvýpočet absolutní hodnoty
9FSQRTvýpočet druhé odmocniny

16. Odkazy na Internetu

  1. Art of Assembly language programming: The 80×87 Floating Point Coprocessors
    https://courses.engr.illinois.edu/ece390/books/artofasm/CH14/CH14-3.html
  2. Art of Assembly language programming: The FPU Instruction Set
    https://courses.engr.illinois.edu/ece390/books/artofasm/CH14/CH14-4.html
  3. INTEL 80387 PROGRAMMER’S REFERENCE MANUAL
    http://www.ragestorm.net/downloads/387intel.txt
  4. x86 Instruction Set Reference: FLD
    http://x86.renejeschke.de/html/file_module_x86_id_100.html
  5. x86 Instruction Set Reference: FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ
    http://x86.renejeschke.de/html/file_module_x86_id_101.html
  6. x86 Instruction Set Reference: BT
    http://x86.renejeschke.de/html/file_module_x86_id_22.html
  7. x86 Instruction Set Reference: BTC
    http://x86.renejeschke.de/html/file_module_x86_id_23.html
  8. x86 Instruction Set Reference: BTR
    http://x86.renejeschke.de/html/file_module_x86_id_24.html
  9. x86 Instruction Set Reference: BTS
    http://x86.renejeschke.de/html/file_module_x86_id_25.html
  10. x86 Instruction Set Reference: BSF
    http://x86.renejeschke.de/html/file_module_x86_id_19.html
  11. x86 Instruction Set Reference: BSR
    http://x86.renejeschke.de/html/file_module_x86_id_20.html
  12. x86 Instruction Set Reference: BSWAP
    http://x86.renejeschke.de/html/file_module_x86_id_21.html
  13. x86 Instruction Set Reference: XCHG
    http://x86.renejeschke.de/html/file_module_x86_id_328.html
  14. x86 Instruction Set Reference: SETcc
    http://x86.renejeschke.de/html/file_module_x86_id_288.html
  15. X86 Assembly/Arithmetic
    https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic
  16. Art of Assembly – Arithmetic Instructions
    http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-2.html
  17. The GNU Assembler Tutorial
    http://tigcc.ticalc.org/doc/gnuasm.html
  18. The GNU Assembler – macros
    http://tigcc.ticalc.org/doc/gnuasm.html#SEC109
  19. ARM subroutines & program stack
    http://www.toves.org/books/armsub/
  20. Generating Mixed Source and Assembly List using GCC
    http://www.systutorials.com/240/generate-a-mixed-source-and-assembly-listing-using-gcc/
  21. Calling subroutines
    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0100a/armasm_cihcfigg.htm
  22. ARM Assembly Language Programming
    http://peter-cockerell.net/aalp/html/frames.html
  23. ASM Flags
    http://www.cavestory.org/guides/csasm/guide/asm_flags.html
  24. Status Register
    https://en.wikipedia.org/wiki/Status_register
  25. Intel x86 JUMP quick reference
    http://unixwiz.net/techtips/x86-jumps.html
  26. Linux assemblers: A comparison of GAS and NASM
    http://www.ibm.com/developerworks/library/l-gas-nasm/index.html
  27. Programovani v assembleru na OS Linux
    http://www.cs.vsb.cz/grygarek/asm/asmlinux.html
  28. Is it worthwhile to learn x86 assembly language today?
    https://www.quora.com/Is-it-worthwhile-to-learn-x86-assembly-language-today?share=1
  29. Why Learn Assembly Language?
    http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language
  30. Is Assembly still relevant?
    http://programmers.stackexchange.com/questions/95836/is-assembly-still-relevant
  31. Why Learning Assembly Language Is Still a Good Idea
    http://www.onlamp.com/pub/a/onlamp/2004/05/06/writegreatcode.html
  32. Assembly language today
    http://beust.com/weblog/2004/06/23/assembly-language-today/
  33. Assembler: Význam assembleru dnes
    http://www.builder.cz/rubriky/assembler/vyznam-assembleru-dnes-155960cz
  34. Assembler pod Linuxem
    http://phoenix.inf.upol.cz/linux/prog/asm.html
  35. AT&T Syntax versus Intel Syntax
    https://www.sourceware.org/binutils/docs-2.12/as.info/i386-Syntax.html
  36. Linux Assembly website
    http://asm.sourceforge.net/
  37. Using Assembly Language in Linux
    http://asm.sourceforge.net/articles/linasm.html
  38. vasm
    http://sun.hasenbraten.de/vasm/
  39. vasm – dokumentace
    http://sun.hasenbraten.de/vasm/release/vasm.html
  40. The Yasm Modular Assembler Project
    http://yasm.tortall.net/
  41. 680×0:AsmOne
    http://www.amigacoding.com/index.php/680×0:AsmOne
  42. ASM-One Macro Assembler
    http://en.wikipedia.org/wiki/ASM-One_Macro_Assembler
  43. ASM-One pages
    http://www.theflamearrows.info/documents/asmone.html
  44. Základní informace o ASM-One
    http://www.theflamearrows.info/documents/asminfo.html
  45. Linux Syscall Reference
    http://syscalls.kernelgrok.com/
  46. Programming from the Ground Up Book – Summary
    http://savannah.nongnu.org/projects/pgubook/
  47. IBM System 360/370 Compiler and Historical Documentation
    http://www.edelweb.fr/Simula/
  48. IBM 700/7000 series
    http://en.wikipedia.org/wiki/IBM_700/7000_series
  49. IBM System/360
    http://en.wikipedia.org/wiki/IBM_System/360
  50. IBM System/370
    http://en.wikipedia.org/wiki/IBM_System/370
  51. Mainframe family tree and chronology
    http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_FT1.html
  52. 704 Data Processing System
    http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_PP704.html
  53. 705 Data Processing System
    http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_PP705.html
  54. The IBM 704
    http://www.columbia.edu/acis/history/704.html
  55. IBM Mainframe album
    http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_album.html
  56. Osmibitové muzeum
    http://osmi.tarbik.com/
  57. Tesla PMI-80
    http://osmi.tarbik.com/cssr/pmi80.html
  58. PMI-80
    http://en.wikipedia.org/wiki/PMI-80
  59. PMI-80
    http://www.old-computers.com/museum/computer.asp?st=1&c=1016
  60. The 6502 overflow flag explained mathematically
    http://www.righto.com/2012/12/the-6502-overflow-flag-explained.html
  61. X86 Opcode and Instruction Reference
    http://ref.x86asm.net/coder32.html