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í
7. Bitová rotace doprava a doleva
8. Bitové rotace prováděné přes příznak přenosu
9. Bitové posuny doprava a doleva
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énka | dec se znaménkem | hex | binárně | |
---|---|---|---|---|
původní hodnota registru | 0 | 0 | 0000 | 0000000000000000 |
po provedení NOT | 65535 | -1 | FFFF | 1111111111111111 |
původní hodnota | 42 | 42 | 002A | 0000000000101010 |
po provedení NOT | 65493 | -43 | FFD5 | 1111111111010101 |
původní hodnota | 12345 | 12345 | 3039 | 0011000000111001 |
po provedení NOT | 53190 | -12346 | CFC6 | 1100111111000110 |
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říznak | Nastavení |
---|---|
Zero flag | nezměněn |
Sign flag | nezměněn |
Carry flag | nezměněn |
Overflow flag | nezmě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ů:
hex | binárně | Zero flag | |
---|---|---|---|
operand 1 | 0000 | 0000000000000000 | |
operand 2 | 0000 | 0000000000000000 | |
výsledek | 0000 | 0000000000000000 | 1 |
operand 1 | 2A2A | 0010101000101010 | |
operand 2 | 00FF | 0000000011111111 | |
výsledek | 002A | 0000000000101010 | 0 |
operand 1 | 0FF0 | 0000111111110000 | |
operand 2 | FF00 | 1111111100000000 | |
výsledek | 0F00 | 0000111100000000 | 0 |
operand 1 | 00FF | 0000000011111111 | |
operand 2 | FF00 | 1111111100000000 | |
výsledek | 0000 | 0000000000000000 | 1 |
Nastavení bitových příznaků uložených v registru EFLAGS:
Příznak | Nastavení |
---|---|
Zero flag | nastaven, pokud je výsledek operace AND provedené bit po bitu nulový |
Sign flag | nastaven na základě nejvyššího bitu operace AND provedené bit po bitu |
Carry flag | vynulován |
Overflow flag | vynulován |
Podporované adresovací režimy:
Operand 1 | Operand 2 |
---|---|
osmibitový registr | osmibitový registr |
osmibitový registr | osmibitová hodnota v RAM |
osmibitový registr | osmibitová konstanta |
osmibitová hodnota v RAM | osmibitová konstanta |
16bitový registr | 16bitový registr |
16bitový registr | 16bitová hodnota v RAM |
16bitový registr | 16bitová konstanta |
16bitová hodnota v RAM | 16bitová konstanta |
32bitový registr | 32bitový registr |
32bitový registr | 32bitová hodnota v RAM |
32bitový registr | 32bitová konstanta |
32bitová hodnota v RAM | 32bitová konstanta |
64bitový registr | 64bitový registr |
64bitový registr | 64bitová hodnota v RAM |
64bitový registr | 64bitová konstanta |
64bitová hodnota v RAM | 64bitová 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:
hex | binárně | Zero flag | |
---|---|---|---|
operand 1 | 0000 | 0000000000000000 | |
operand 2 | 0000 | 0000000000000000 | |
výsledek | 0000 | 0000000000000000 | 1 |
operand 1 | 2A2A | 0010101000101010 | |
operand 2 | 00FF | 0000000011111111 | |
výsledek | 002A | 0000000000101010 | 0 |
operand 1 | 0FF0 | 0000111111110000 | |
operand 2 | FF00 | 1111111100000000 | |
výsledek | 0F00 | 0000111100000000 | 0 |
operand 1 | 00FF | 0000000011111111 | |
operand 2 | FF00 | 1111111100000000 | |
výsledek | 0000 | 0000000000000000 | 1 |
Nastavení bitových příznaků uložených v registru EFLAGS:
Příznak | Nastavení |
---|---|
Zero flag | nastaven, pokud je výsledek operace AND provedené bit po bitu nulový |
Sign flag | nastaven na základě nejvyššího bitu operace AND provedené bit po bitu |
Carry flag | vynulován |
Overflow flag | vynulován |
Podporované adresovací režimy:
Operand 1 | Operand 2 |
---|---|
osmibitový registr | osmibitový registr |
osmibitový registr | osmibitová hodnota v RAM |
osmibitový registr | osmibitová konstanta |
osmibitová hodnota v RAM | osmibitová konstanta |
16bitový registr | 16bitový registr |
16bitový registr | 16bitová hodnota v RAM |
16bitový registr | 16bitová konstanta |
16bitová hodnota v RAM | 16bitová konstanta |
32bitový registr | 32bitový registr |
32bitový registr | 32bitová hodnota v RAM |
32bitový registr | 32bitová konstanta |
32bitová hodnota v RAM | 32bitová konstanta |
64bitový registr | 64bitový registr |
64bitový registr | 64bitová hodnota v RAM |
64bitový registr | 64bitová konstanta |
64bitová hodnota v RAM | 64bitová 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:
hex | binárně | Zero flag | |
---|---|---|---|
operand 1 | 0000 | 0000000000000000 | |
operand 2 | 0000 | 0000000000000000 | |
výsledek | 0000 | 0000000000000000 | 1 |
operand 1 | 2A2A | 0010101000101010 | |
operand 2 | 00FF | 0000000011111111 | |
výsledek | 2AFF | 0010101011111111 | 0 |
operand 1 | 0FF0 | 0000111111110000 | |
operand 2 | FF00 | 1111111100000000 | |
výsledek | FFF0 | 1111111111110000 | 0 |
operand 1 | 00FF | 0000000011111111 | |
operand 2 | FF00 | 1111111100000000 | |
výsledek | FFFF | 1111111111111111 | 0 |
Nastavení bitových příznaků uložených v registru EFLAGS:
Příznak | Nastavení |
---|---|
Zero flag | nastaven, pokud je výsledek operace OR provedené bit po bitu nulový |
Sign flag | nastaven na základě nejvyššího bitu operace OR provedené bit po bitu |
Carry flag | vynulován |
Overflow flag | vynulován |
Podporované adresovací režimy:
Operand 1 | Operand 2 |
---|---|
osmibitový registr | osmibitový registr |
osmibitový registr | osmibitová hodnota v RAM |
osmibitový registr | osmibitová konstanta |
osmibitová hodnota v RAM | osmibitová konstanta |
16bitový registr | 16bitový registr |
16bitový registr | 16bitová hodnota v RAM |
16bitový registr | 16bitová konstanta |
16bitová hodnota v RAM | 16bitová konstanta |
32bitový registr | 32bitový registr |
32bitový registr | 32bitová hodnota v RAM |
32bitový registr | 32bitová konstanta |
32bitová hodnota v RAM | 32bitová konstanta |
64bitový registr | 64bitový registr |
64bitový registr | 64bitová hodnota v RAM |
64bitový registr | 64bitová konstanta |
64bitová hodnota v RAM | 64bitová 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).
hex | binárně | Zero flag | |
---|---|---|---|
operand 1 | 0000 | 0000000000000000 | |
operand 2 | 0000 | 0000000000000000 | |
výsledek | 0000 | 0000000000000000 | 1 |
operand 1 | 2A2A | 0010101000101010 | |
operand 2 | 00FF | 0000000011111111 | |
výsledek | 2AD5 | 0010101011010101 | 0 |
operand 1 | 2A2A | 0010101000101010 | |
operand 2 | 2A2A | 0010101000101010 | |
výsledek | 0000 | 0000000000000000 | 1 |
operand 1 | 0FF0 | 0000111111110000 | |
operand 2 | FF00 | 1111111100000000 | |
výsledek | F0F0 | 1111000011110000 | 0 |
operand 1 | 00FF | 0000000011111111 | |
operand 2 | FF00 | 1111111100000000 | |
výsledek | FFFF | 1111111111111111 | 0 |
operand 1 | 002A | 0000000000101010 | |
operand 2 | FFFF | 1111111111111111 | |
výsledek | FFD5 | 1111111111010101 | 0 |
Nastavení bitových příznaků uložených v registru EFLAGS:
Příznak | Nastavení |
---|---|
Zero flag | nastaven, pokud je výsledek operace XOR provedené bit po bitu nulový |
Sign flag | nastaven na základě nejvyššího bitu operace XOR provedené bit po bitu |
Carry flag | vynulován |
Overflow flag | vynulován |
Podporované adresovací režimy:
Operand 1 | Operand 2 |
---|---|
osmibitový registr | osmibitový registr |
osmibitový registr | osmibitová hodnota v RAM |
osmibitový registr | osmibitová konstanta |
osmibitová hodnota v RAM | osmibitová konstanta |
16bitový registr | 16bitový registr |
16bitový registr | 16bitová hodnota v RAM |
16bitový registr | 16bitová konstanta |
16bitová hodnota v RAM | 16bitová konstanta |
32bitový registr | 32bitový registr |
32bitový registr | 32bitová hodnota v RAM |
32bitový registr | 32bitová konstanta |
32bitová hodnota v RAM | 32bitová konstanta |
64bitový registr | 64bitový registr |
64bitový registr | 64bitová hodnota v RAM |
64bitový registr | 64bitová konstanta |
64bitová hodnota v RAM | 64bitová 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:
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říznak | Nastavení |
---|---|
Zero flag | nezměněn |
Sign flag | nezměněn |
Carry flag | bit, který byl rotací přesunut na začátek/konec registru |
Overflow flag | nastaven 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:
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říznak | Nastavení |
---|---|
Zero flag | nezměněn |
Sign flag | nezměněn |
Carry flag | bit, který byl rotací přesunut na začátek/konec registru |
Overflow flag | nastaven 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říznak | Nastavení |
---|---|
Zero flag | nastaven při nulovém výsledku |
Sign flag | nastaven podle nejvyššího bitu výsledku |
Carry flag | bit, který byl rotací přesunut na začátek/konec registru |
Overflow flag | nastaven 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 (SAR – Shift 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.
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říznak | Nastavení |
---|---|
Zero flag | nastaven při nulovém výsledku |
Sign flag | nastaven podle nejvyššího bitu výsledku |
Carry flag | bit, který byl rotací přesunut na začátek/konec registru |
Overflow flag | nastaven 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
- x86 Instruction Set Reference
http://x86.renejeschke.de/ - x86 Instruction Set Reference: Logical AND
http://x86.renejeschke.de/html/file_module_x86_id_12.html - x86 Instruction Set Reference: Logical Inclusive OR
http://x86.renejeschke.de/html/file_module_x86_id_219.html - x86 Instruction Set Reference: Logical Exclusive OR
http://x86.renejeschke.de/html/file_module_x86_id_330.html - x86 Instruction Set Reference: One's Complement Negation
http://x86.renejeschke.de/html/file_module_x86_id_218.html - x86 Instruction Set Reference: RCL/RCR/ROL/ROR
http://x86.renejeschke.de/html/file_module_x86_id_273.html - x86 Instruction Set Reference: SAL/SAR/SHL/SHR
http://x86.renejeschke.de/html/file_module_x86_id_285.html - X86 Assembly/Arithmetic
https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic - Art of Assembly - Arithmetic Instructions
http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-2.html - The GNU Assembler Tutorial
http://tigcc.ticalc.org/doc/gnuasm.html - The GNU Assembler - macros
http://tigcc.ticalc.org/doc/gnuasm.html#SEC109 - ARM subroutines & program stack
http://www.toves.org/books/armsub/ - Generating Mixed Source and Assembly List using GCC
http://www.systutorials.com/240/generate-a-mixed-source-and-assembly-listing-using-gcc/ - Calling subroutines
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0100a/armasm_cihcfigg.htm - ARM Assembly Language Programming
http://peter-cockerell.net/aalp/html/frames.html - ASM Flags
http://www.cavestory.org/guides/csasm/guide/asm_flags.html - Status Register
https://en.wikipedia.org/wiki/Status_register - Intel x86 JUMP quick reference
http://unixwiz.net/techtips/x86-jumps.html - 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 - Assembler pod Linuxem
http://phoenix.inf.upol.cz/linux/prog/asm.html - AT&T Syntax versus Intel Syntax
https://www.sourceware.org/binutils/docs-2.12/as.info/i386-Syntax.html - Linux Assembly website
http://asm.sourceforge.net/ - Using Assembly Language in Linux
http://asm.sourceforge.net/articles/linasm.html - vasm
http://sun.hasenbraten.de/vasm/ - vasm – dokumentace
http://sun.hasenbraten.de/vasm/release/vasm.html - The Yasm Modular Assembler Project
http://yasm.tortall.net/ - 680x0:AsmOne
http://www.amigacoding.com/index.php/680x0:AsmOne - ASM-One Macro Assembler
http://en.wikipedia.org/wiki/ASM-One_Macro_Assembler - ASM-One pages
http://www.theflamearrows.info/documents/asmone.html - Základní informace o ASM-One
http://www.theflamearrows.info/documents/asminfo.html - Linux Syscall Reference
http://syscalls.kernelgrok.com/ - Programming from the Ground Up Book - Summary
http://savannah.nongnu.org/projects/pgubook/ - IBM System 360/370 Compiler and Historical Documentation
http://www.edelweb.fr/Simula/ - IBM 700/7000 series
http://en.wikipedia.org/wiki/IBM_700/7000_series - IBM System/360
http://en.wikipedia.org/wiki/IBM_System/360 - IBM System/370
http://en.wikipedia.org/wiki/IBM_System/370 - Mainframe family tree and chronology
http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_FT1.html - 704 Data Processing System
http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_PP704.html - 705 Data Processing System
http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_PP705.html - The IBM 704
http://www.columbia.edu/acis/history/704.html - IBM Mainframe album
http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_album.html - Osmibitové muzeum
http://osmi.tarbik.com/ - Tesla PMI-80
http://osmi.tarbik.com/cssr/pmi80.html - PMI-80
http://en.wikipedia.org/wiki/PMI-80 - PMI-80
http://www.old-computers.com/museum/computer.asp?st=1&c=1016 - The 6502 overflow flag explained mathematically
http://www.righto.com/2012/12/the-6502-overflow-flag-explained.html - X86 Opcode and Instruction Reference
http://ref.x86asm.net/coder32.html