Nedílnou součástí většiny programů psaných v assembleru jsou i instrukce provádějící logické a bitové operace. Do této skupiny patří zejména instrukce NOT, AND, OR a XOR doplněné o instrukci nazvanou jednoduše TEST. Nesmíme ovšem zapomenout ani na bitové rotace, bitové posuny a aritmetický posun doprava, tedy na instrukce s mnemotechnickými zkratkami ROL, ROR, RCL, RCR, SHL, SHR a konečně SAR.

Obsah

1. Logické a bitové operace na mikroprocesorech řady x86

2. Strojová instrukce NOT: negace bit po bitu

3. Strojová instrukce TEST a příklady jejího využití

4. Strojová instrukce AND

5. Strojová instrukce OR

6. Strojová instrukce XOR

7. Bitová rotace doprava a doleva

8. Bitové rotace prováděné přes příznak přenosu

9. Bitové posuny doprava a doleva

10. Aritmetický posun doprava

11. Odkazy na Internetu

1. Logické a bitové operace na mikroprocesorech řady x86

Naprostá většina aritmeticko-logických jednotek použitých v mikroprocesorech podporuje provádění nejméně čtyř základních logických operací (aplikovaných bit po bitu), ke kterým se v některých případech mohou přidat i operace další. Jedná se o operaci logického bitového součinu (AND) nad všemi korespondujícími bity pracovních registrů či jednoho pracovního registru a buňky operační paměti či konstanty, dále pak o operaci logického součtu (OR), nonekvivalenci (XOR či EOR) a konečně o operaci bitové negace (COM popř. ,NOT) všech bitů jednoho z pracovních registrů. První tři zmíněné operace, tj. logický součin, logický součet a nonekvivalence, jsou operacemi binárními, což znamená, že vyžadují dva operandy (většinou dva pracovní registry, registr a konstantu či registr a buňku v operační paměti), poslední operace – negace –, je operací unární, tj. na vstupu vyžaduje pouze obsah pracovního registru či buňku v operační paměti.

V dnešním článku se zaměříme na způsob implementace těchto operací na mikroprocesorech s 32bitovou architekturou x86 i s 64bitovou architekturou x86-64. U těchto procesorů nalezneme i instrukci TEST, která vlastně provádí prakticky stejnou operaci jako instrukce AND, ovšem bez uložení výsledku zpět do pracovního registru (jedná se tedy o obdobu dvojice instrukcí SUB a CMP). Posléze si popíšeme i další důležité a relativně často používané operace, konkrétně bitové posuny a rotace.

2. Strojová instrukce NOT: negace bit po bitu

Nejjednodušší strojovou instrukcí manipulující s jednotlivými bity zvoleného pracovního registru či buňky operační paměti je instrukce nazvaná NOT. Tato instrukce zneguje každý bit svého jediného operandu, přitom se však, na rozdíl od všech dalších dále popsaných instrukcí, nijak neovlivní hodnoty příznakových bitů. Ohledně mnemotechnické zkratky této instrukce panuje poměrně velký zmatek, protože někteří výrobci mikroprocesorů (kteří většinou současně zkratky instrukcí pro svoje výrobky definují) používají zkratku NEG či COM, a jiní naopak zkratku NEG vyhradili pro instrukci určenou pro vytvoření dvojkového doplňku, tj. změny znaménka čísla (což je i případ mikroprocesorů Intel řady x86). Podívejme se, jak tato instrukce pracuje při použití šestnáctibitového registru:

dec bez znaménkadec se znaménkemhexbinárně
původní hodnota registru0000000000000000000000
po provedení NOT65535-1FFFF1111111111111111
původní hodnota4242002A0000000000101010
po provedení NOT65493-43FFD51111111111010101
původní hodnota123451234530390011000000111001
po provedení NOT53190-12346CFC61100111111000110

Poznámka: instrukce NEG skutečně pouze neguje všechny bity, pokud potřebujete získat číslo s opačným znaménkem, použijte instrukci NEG.

Nastavení bitových příznaků uložených v registru EFLAGS:

PříznakNastavení
Zero flagnezměněn
Sign flagnezměněn
Carry flagnezměněn
Overflow flagnezměněn

Podporované adresovací režimy:

Operand
osmibitový registr
16bitový registr
32bitový registr
64bitový registr
osmibitová hodnota v RAM
16bitová hodnota v RAM
32bitová hodnota v RAM
64bitová hodnota v RAM

Vidíme, že adresování operandu je u této instrukce velmi jednoduché, protože je použit jediný operand.

3. Strojová instrukce TEST a příklady jejího využití

Strojová instrukce TEST slouží k provedení logické operace konjunkce (and) bit po bitu s požadovanou dvojicí pracovních registrů, popř. s jedním pracovním registrem a obsahem buňky načtené z operační paměti (zpracovat lze jednotlivé bajty, 16bitová slova, 32bitová slova a nově i 64bitová slova). Jinými slovy se jedná o stejnou funkci, jakou provádí dále popsaná instrukce AND. Jediný, zato však podstatný rozdíl spočívá v tom, že zatímco instrukce AND uložila výsledek operace do pracovního registru, který byl jejím prvním operandem, tak instrukce TEST výsledek operace ihned „zapomene“, tj. obsah žádného pracovního registru se nezmění. K čemu je však vlastně tato instrukce užitečná, když se výsledek operace AND ihned zapomene? Asi jste již správně uhodli, že výsledkem spuštění této instrukce budou pozměněné příznakové bity, podobně jako tomu bylo u minule popsané strojové instrukce CMP.

Instrukce TEST nastaví čtveřici příznakových bitů. Jedná se o Carry Flag (CF), Zero Flag (ZF), Sign Flag (SF) i Overflow Flag (OF). Carry Flag a Overflow Flag jsou touto instrukcí vynulovány, čehož je možné využít k některým optimalizacím. Příznakový bit Zero flag se nastaví v závislosti na tom, zda je výsledek konjunkce nulový či nenulový. A konečně Sign Flag je nastaven podle nejvyššího bitu výsledku konjunkce. Tato instrukce se používá především při implementaci různých podmínek či programových smyček, podobně jako minule popsaná instrukce CMP. K čemu lze tuto znalost využít? Například pro otestování znaménka hodnoty uložené v nějakém registru:

TEST EAX, EAX
JS je_zaporne

Na rozdíl od instrukce CMP EAX, 0 je TEST EAX, EAX kratší (nenačítá se konstanta) a ve většině případů i o několik strojových cyklů rychlejší.

Nastavení příznaku Zero flag po provedení operace TEST nad dvojicí šestnáctibitových registrů:

hexbinárněZero flag
operand 100000000000000000000
operand 200000000000000000000
výsledek000000000000000000001
operand 12A2A0010101000101010
operand 200FF0000000011111111
výsledek002A00000000001010100
operand 10FF00000111111110000
operand 2FF001111111100000000
výsledek0F0000001111000000000
operand 100FF0000000011111111
operand 2FF001111111100000000
výsledek000000000000000000001

Nastavení bitových příznaků uložených v registru EFLAGS:

PříznakNastavení
Zero flagnastaven, pokud je výsledek operace AND provedené bit po bitu nulový
Sign flagnastaven na základě nejvyššího bitu operace AND provedené bit po bitu
Carry flagvynulován
Overflow flagvynulován

Podporované adresovací režimy:

Operand 1Operand 2
osmibitový registrosmibitový registr
osmibitový registrosmibitová hodnota v RAM
osmibitový registrosmibitová konstanta
osmibitová hodnota v RAMosmibitová konstanta
16bitový registr16bitový registr
16bitový registr16bitová hodnota v RAM
16bitový registr16bitová konstanta
16bitová hodnota v RAM16bitová konstanta
32bitový registr32bitový registr
32bitový registr32bitová hodnota v RAM
32bitový registr32bitová konstanta
32bitová hodnota v RAM32bitová konstanta
64bitový registr64bitový registr
64bitový registr64bitová hodnota v RAM
64bitový registr64bitová konstanta
64bitová hodnota v RAM64bitová konstanta

4. Strojová instrukce AND

V programech či jejich částech psaných ve strojovém kódu nebo jazyku symbolických instrukcí se velmi často používá logická operace AND, která provádí logický součin obsahu vybraného pracovního registru s obsahem jiného pracovního registru či s obsahem vybrané buňky (buněk) načtených z operační paměti (popř. lze použít i konstantu). Logický součin je při použití této instrukce prováděn bit po bitu. Výsledek je uložen do jednoho z pracovních registrů v závislosti na adresní části instrukce.

Podle výsledku operace je nastaven příznak Zero flag (výsledek je nulový či nenulový) a Sign Flag (podle nejvyššího bitu výsledku), naopak příznaky Carry Flag a Overflow Flag jsou vynulovány. Tato operace slouží jak k implementaci logického součinu s pravdivostními hodnotami (pracovní registry v tomto případě typicky obsahují hodnoty 0x00000000 nebo 0xFFFFFFFF), tak i k maskování vybraných bitů jednoho z pracovních registrů. Obsah druhého pracovního registru slouží jako takzvaná maska: pokud je nějaký bit masky roven nule, je vynulován i příslušný bit prvního pracovního registru. Následují příklady použití této instrukce:

hexbinárněZero flag
operand 100000000000000000000
operand 200000000000000000000
výsledek000000000000000000001
operand 12A2A0010101000101010
operand 200FF0000000011111111
výsledek002A00000000001010100
operand 10FF00000111111110000
operand 2FF001111111100000000
výsledek0F0000001111000000000
operand 100FF0000000011111111
operand 2FF001111111100000000
výsledek000000000000000000001

Nastavení bitových příznaků uložených v registru EFLAGS:

PříznakNastavení
Zero flagnastaven, pokud je výsledek operace AND provedené bit po bitu nulový
Sign flagnastaven na základě nejvyššího bitu operace AND provedené bit po bitu
Carry flagvynulován
Overflow flagvynulován

Podporované adresovací režimy:

Operand 1Operand 2
osmibitový registrosmibitový registr
osmibitový registrosmibitová hodnota v RAM
osmibitový registrosmibitová konstanta
osmibitová hodnota v RAMosmibitová konstanta
16bitový registr16bitový registr
16bitový registr16bitová hodnota v RAM
16bitový registr16bitová konstanta
16bitová hodnota v RAM16bitová konstanta
32bitový registr32bitový registr
32bitový registr32bitová hodnota v RAM
32bitový registr32bitová konstanta
32bitová hodnota v RAM32bitová konstanta
64bitový registr64bitový registr
64bitový registr64bitová hodnota v RAM
64bitový registr64bitová konstanta
64bitová hodnota v RAM64bitová konstanta

5. Strojová instrukce OR

Strojová instrukce OR je určena k provedení logického součtu (opět bit po bitu) s obsahy dvou pracovních registrů, popř. registru a obsahu vybrané buňky operační paměti. Výsledek je uložen do registru, který tvoří první parametr instrukce, tj. je uveden na prvním místě při zápisu instrukce v assembleru. Tato operace se používá například pro nastavení určených bitů pracovního registru na jedničku (jedná se ve skutečnosti opět o maskování, i když opačného významu, než tomu bylo u instrukce AND) nebo pro implementaci booleovských (pravdivostních) výrazů. Podle výsledku aplikace operace OR se nastaví příznaky Zero flag a Sign flag, zatímco obsahy příznaků Carry flag a Overflow flag jsou vynulovány:

hexbinárněZero flag
operand 100000000000000000000
operand 200000000000000000000
výsledek000000000000000000001
operand 12A2A0010101000101010
operand 200FF0000000011111111
výsledek2AFF00101010111111110
operand 10FF00000111111110000
operand 2FF001111111100000000
výsledekFFF011111111111100000
operand 100FF0000000011111111
operand 2FF001111111100000000
výsledekFFFF11111111111111110

Nastavení bitových příznaků uložených v registru EFLAGS:

PříznakNastavení
Zero flagnastaven, pokud je výsledek operace OR provedené bit po bitu nulový
Sign flagnastaven na základě nejvyššího bitu operace OR provedené bit po bitu
Carry flagvynulován
Overflow flagvynulován

Podporované adresovací režimy:

Operand 1Operand 2
osmibitový registrosmibitový registr
osmibitový registrosmibitová hodnota v RAM
osmibitový registrosmibitová konstanta
osmibitová hodnota v RAMosmibitová konstanta
16bitový registr16bitový registr
16bitový registr16bitová hodnota v RAM
16bitový registr16bitová konstanta
16bitová hodnota v RAM16bitová konstanta
32bitový registr32bitový registr
32bitový registr32bitová hodnota v RAM
32bitový registr32bitová konstanta
32bitová hodnota v RAM32bitová konstanta
64bitový registr64bitový registr
64bitový registr64bitová hodnota v RAM
64bitový registr64bitová konstanta
64bitová hodnota v RAM64bitová konstanta

6. Strojová instrukce XOR

S využitím strojové instrukce XOR, která bývá v některých assemblerech označována mnemotechnickou zkratkou EOR, se provádí operace nonekvivalence, tj. exkluzivní (výlučný) logický součet obou zadaných operandů a to opět, stejně jako u předchozích dvou instrukcí, bit po bitu. Podle výsledku této instrukce jsou nastaveny příznaky Zero flag a Sign flag, podobně jako u výše uvedených operací AND a OR.

Zatímco logický součet i součin se mj. používá pro implementaci logických výrazů známých z vyšších programovacích jazyků, je operace nonekvivalence používána k selektivní negaci vybraných bitů, protože ve chvíli, kdy jsou oba korespondující bity nastaveny na logickou jedničku, je výsledkem logická nula. Tuto instrukci lze využít v mnoha oblastech, například v počítačové grafice, šifrování, generátorech pseudonáhodných posloupností čísel (RND), konstrukci kontrolních součtů či cyklických kódů (CRC) atd. Je přitom využito faktu, že dvojí použití operace XOR se stejným druhým operandem vede k tomu, že výsledkem je původní hodnota, předaná operaci v prvním kroku. Následují příklady použití, ve kterých stojí za povšimnutí „negující“ vlastnost této instrukce (poslední příklad) i to, že aplikace nonekvivalence na tu samou hodnotu dává nulový výsledek (třetí příklad).

hexbinárněZero flag
operand 100000000000000000000
operand 200000000000000000000
výsledek000000000000000000001
operand 12A2A0010101000101010
operand 200FF0000000011111111
výsledek2AD500101010110101010
operand 12A2A0010101000101010
operand 22A2A0010101000101010
výsledek000000000000000000001
operand 10FF00000111111110000
operand 2FF001111111100000000
výsledekF0F011110000111100000
operand 100FF0000000011111111
operand 2FF001111111100000000
výsledekFFFF11111111111111110
operand 1002A0000000000101010
operand 2FFFF1111111111111111
výsledekFFD511111111110101010

Nastavení bitových příznaků uložených v registru EFLAGS:

PříznakNastavení
Zero flagnastaven, pokud je výsledek operace XOR provedené bit po bitu nulový
Sign flagnastaven na základě nejvyššího bitu operace XOR provedené bit po bitu
Carry flagvynulován
Overflow flagvynulován

Podporované adresovací režimy:

Operand 1Operand 2
osmibitový registrosmibitový registr
osmibitový registrosmibitová hodnota v RAM
osmibitový registrosmibitová konstanta
osmibitová hodnota v RAMosmibitová konstanta
16bitový registr16bitový registr
16bitový registr16bitová hodnota v RAM
16bitový registr16bitová konstanta
16bitová hodnota v RAM16bitová konstanta
32bitový registr32bitový registr
32bitový registr32bitová hodnota v RAM
32bitový registr32bitová konstanta
32bitová hodnota v RAM32bitová konstanta
64bitový registr64bitový registr
64bitový registr64bitová hodnota v RAM
64bitový registr64bitová konstanta
64bitová hodnota v RAM64bitová konstanta

7. Bitová rotace doprava a doleva

V assembleru se poměrně často používají instrukce provádějící takzvané bitové rotace. O co se vlastně jedná? Jde o posun všech bitů v některém z pracovních registrů, ovšem takovým způsobem, že se jedná o uzavřenou smyčku, tj. obsah bitu, který by se provedením posunu ztratil (byl by vysunut), je naopak zkopírován na vstup. Kromě toho se tento bit zkopíruje do příznakového bitu Carry flag, což není samoúčelné, protože se této skutečnosti dá využít pro provedení skoku v závislosti na hodnotě jednoho konkrétního bitu, implementaci generátoru pseudonáhodných čísel nebo při programování aritmetických operací násobení a dělení (to však již na moderních mikroprocesorech postrádá význam). Pro takto chápanou bitovou rotaci existují dvě instrukce, první pro rotaci obsahu pracovního registru doleva a druhá pro rotaci doprava. Každá instrukce způsobí rotaci buď pouze o jeden bit, popř. o zadaný počet bitů (mikroprocesory však kvůli optimalizacím maskují čítač rotace, takže se maximálně provede 32 či 64 rotací). Nákres rotace doleva i doprava, je naznačen na obrázku:

01

Obrázek 1: Bitová rotace doleva a doprava (zde ukázána se 16bitovým operandem).

Instrukce pro rotaci doleva se jmenuje ROL, instrukce pro rotaci doprava logicky ROR. Kromě příznaku Carry flag může být nastaven i příznak Overflow flag, ovšem pouze za toho předpokladu, že se rotuje o jediný bit (v jiném případě chybí správná sémantika pro tento příznak):

PříznakNastavení
Zero flagnezměněn
Sign flagnezměněn
Carry flagbit, který byl rotací přesunut na začátek/konec registru
Overflow flagnastaven pouze při rotaci o jediný bit, má význam jako při sčítání a odčítání

8. Bitové rotace prováděné přes příznak přenosu

Kromě běžných bitových rotací popsaných v předchozí kapitole se setkáme i s rotacemi prováděnými přes příznak přenosu (Carry flag). V podstatě se jedná o rozšíření bitové šířky rotovaného registru o jeden bit, který je představovaný právě příznakem přenosu, tj. neprovádí se rotace 8, 16, 32 či 64 bitů, ale bitů devíti, 17, 33 či 65. Použití těchto typů rotací spočívá například v implementaci víceslovní aritmetiky (rotuje se přes větší množství slov), popř. při požadavku na vložení hodnoty příznaku přenosu do určeného bitu pracovního registru (booleovské operace). Nákres rotace doleva i doprava přes příznak přenosu, je naznačen na obrázku:

02

Obrázek 2: Bitová rotace doleva a doprava přes příznak přenosu (zde ukázána se 16bitovým operandem).

Instrukce pro rotaci doleva přes příznak přenosu se jmenuje RCL, instrukce pro rotaci doprava přes příznak přenosu pak RCR. Kromě příznaku Carry flag může být, podobně jako tomu bylo u instrukcí ROL a ROR nastaven i příznak Overflow flag, ovšem pouze za toho předpokladu, že se rotuje o jediný bit (v jiném případě chybí správná sémantika pro tento příznak):

PříznakNastavení
Zero flagnezměněn
Sign flagnezměněn
Carry flagbit, který byl rotací přesunut na začátek/konec registru
Overflow flagnastaven pouze při rotaci o jediný bit, má význam jako při sčítání a odčítání

Poznámka: u jiných typů mikroprocesorů se setkáme s odlišnými mnemotechnickými zkratkami těchto instrukcí, například namísto RCL se používá RLC či jen RL.

9. Bitové posuny doprava a doleva

Další dvě strojové instrukce, s nimiž se dnes alespoň ve stručnosti seznámíme, mají mnemotechnické zkratky SHL a SHR. Tyto zkratky znamenají Shift Left a Shift Right, tedy bitový posun doleva a doprava. Od rotací se bitové posuny odliší především tím, že se při posunu doleva do nejnižšího bitu vždy vloží nula a při posunu doprava se do nejvyššího bitu taktéž uloží nula (při rotacích se naproti tomu namísto nuly použil příznak přenosu). K čemu je možné tyto instrukce využít? Typickým příkladem je optimalizace násobení mocninou dvou (instrukce SHL) či naopak dělení mocninou dvou (instrukce SHR). Musíme však mít na paměti důležitý fakt, že SHR lze použít pouze pro hodnoty bez znaménka (unsigned). Pro hodnoty se znaménkem je nutné použít instrukci SAR popsanou v navazující kapitole.

Nastavení bitových příznaků uložených v registru EFLAGS:

PříznakNastavení
Zero flagnastaven při nulovém výsledku
Sign flagnastaven podle nejvyššího bitu výsledku
Carry flagbit, který byl rotací přesunut na začátek/konec registru
Overflow flagnastaven pouze při rotaci o jediný bit, má význam jako při sčítání a odčítání

Poznámka: příznaky nejsou nastaveny ve chvíli, kdy je posun proveden o 0 bitů, i když by se teoreticky Zero flag a Sign flag nastavit mohl.

10. Aritmetický posun doprava

K výše popsané šestici bitových rotací a posunů nalezneme v instrukční sadě mikroprocesorů řady x86 a x86-64 i takzvaný aritmetický posun doprava (SARShift Arithmetic Right). Jedná se vlastně o obdobu bitového posunu doprava (SHR), ovšem s tím rozdílem, že obsah nejvyššího bitu zůstává za všech okolností zachován (a samozřejmě je ještě zkopírován do druhého nejvyššího bitu). Pokud si uvědomíme, jakým způsobem jsou reprezentovány hodnoty v systému dvojkového doplňku (viz předchozí části tohoto seriálu), je zřejmé, že tato instrukce ve většině případů (99,99% u šestnáctibitových čísel) provádí dělení dvěma, a to i pro záporné hodnoty. Pro aritmetický posun doleva žádná specializovaná instrukce není dostupná, protože ji lze nahradit běžným posunem (platí i pro záporná čísla reprezentovaná v systému dvojkového doplňku). Mnoho assemblerů sice nabízí instrukci SAL, ta je však kódována stejným způsobem jako instrukce SHL.

03

Obrázek 3: Aritmetický posun doprava (zde ukázán se 16bitovým operandem).

Nastavení bitových příznaků uložených v registru EFLAGS:

PříznakNastavení
Zero flagnastaven při nulovém výsledku
Sign flagnastaven podle nejvyššího bitu výsledku
Carry flagbit, který byl rotací přesunut na začátek/konec registru
Overflow flagnastaven pouze při rotaci o jediný bit, má význam jako při sčítání a odčítání

Poznámka: příznaky nejsou nastaveny ve chvíli, kdy je posun proveden o 0 bitů, i když by se teoreticky Zero flag a Sign flag nastavit mohl.

11. Odkazy na Internetu

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