V již dvacáté první části seriálu o použití assembleru v Linuxu dokončíme téma, kterému jsme se začali věnovat minule. Jedná se o způsob použití podmínek (resp. přesněji řečeno instrukcí s podmínkami) při zpracování dat na moderní 64bitové mikroprocesorové architektuře AArch64. Procesory s touto architekturou totiž kromě podmíněných skoků podporují i některé další instrukce s podmínkou, které byly navrženy a implementovány na základě výsledků studie reálných aplikací.
Obsah
1. Použití assembleru v Linuxu: podmínky při zpracování dat na architektuře AArch64
2. Již známé instrukce: podmíněné skoky
4. Instrukce CSET – Conditional Set
5. Instrukce CSETM – Conditional Set Mask
6. Instrukce CSEL – Conditional Select
7. Instrukce CSINV – Conditional Select Invert
8. Instrukce CSINC – Conditional Select Increment
9. Instrukce CSNEG – Conditional Select Negate
10. Instrukce CINC – Conditional Increment
11. Instrukce CINV – Conditional Invert
12. Instrukce CNEG – Conditional Negate
13. Instrukce TBZ a TBNZ (Test and Branch...)
1. Použití assembleru v Linuxu: podmínky při zpracování dat na architektuře AArch64
V dnešní části seriálu o použití assembleru v Linuxu se zaměříme na poměrně zajímavou a prozatím relativně novou oblast. Jedná se o speciální instrukce implementované na moderní mikroprocesorové architektuře AArch64, které prování specifikovanou činnost pouze za předpokladu, že je splněna nějaká zadaná podmínka (kód podmínky je přitom součástí instrukčního slova). Připomeňme si, že na rozdíl od původní 32bitové architektury ARM (dnes označované ARM32) nemají všechny instrukce na AArch64 rezervovány čtyři nejvyšší bity pro specifikaci podmínky. Tato vlastnost byla na základě analýzy existujících programových strojových kódů zrušena a podmínky je tak možné použít jen u vybrané množiny instrukcí. Do této množiny byly zahrnuty i zcela nové instrukce, které na ARM32 nenalezneme, což je opět důsledek analýzy stávajících strojových kódů, ale i studia funkce překladačů.
Poznámka: podle některých vývojářů může mít extenzivní použití příznakových bitů negativní vliv na výkonnost procesoru, což je však téma, které je řešeno nejenom na AArch64, ale i na x86-64.
Připomeňme si, že na procesorové architektuře AArch64 je použito celkem čtrnáct různých podmínek, k nimž se někdy přidává i pseudopodmínka AL neboli Any/Always. V tomto případě se samozřejmě o žádnou skutečnou podmínku nejedná, neboť je instrukce provedena v každém případě.
Prvních šest podmínek testuje hodnotu pouze jediného bitového příznaku, a to N (negative), Z (zero) či V (overflow):
| Kód | Přípona | Význam | Testovaná podmínka | 
|---|---|---|---|
| 0000 | EQ | Z = 1 | rovnost po porovnání (či nulový výsledek) | 
| 0001 | NE | Z = 0 | nerovnost po porovnání (či nenulový výsledek) | 
| 0100 | MI | N = 1 | výsledek je záporný | 
| 0101 | PL | N = 0 | výsledek je kladný či nulový | 
| 0110 | VS | V = 1 | nastalo přetečení (overflow) | 
| 0111 | VC | V = 0 | nenastalo přetečení (overflow) | 
| 1110 | AL | Any/Always | většinou se nezapisuje, implicitní podmínka | 
Další čtyři podmínkové kódy se většinou používají při porovnávání dvou hodnot bez znaménka (unsigned). V těchto případech se testují stavy příznakových bitů C (carry) a Z (zero), přesněji řečeno kombinace těchto bitů:
| Kód | Přípona | Význam | Testovaná podmínka | 
|---|---|---|---|
| 0010 | CS/HS | C = 1 | ≥ | 
| 0011 | CC/LO | C = 0 | < | 
| 1000 | HI | C = 1 & Z = 0 | > | 
| 1001 | LS | C = 0 | Z = 1 | ≤ | 
Poslední čtyři podmínkové kódy se používají pro porovnávání hodnot se znaménkem (signed). V těchto případech se namísto příznakových bitů (C) carry a (Z) zero testují kombinace bitů (N) negative, (V) overflow a (Z) zero:
| Kód | Přípona | Význam | Testovaná podmínka | 
|---|---|---|---|
| 1010 | GE | N == V | ≥ | 
| 1011 | LT | N ≠ V | < | 
| 1100 | GT | Z = 0, N = V | > | 
| 1101 | LE | Z = 1, N ≠ V | ≤ | 
Důležité je, že všechny dále popsané instrukce podporují všechny podmínky. Výjimku tvoří minule popsané instrukce CBZ a CBNZ, které pouze testovaly nulovost či naopak nenulovost vybraného pracovního registru.
2. Již známé instrukce: podmíněné skoky
Již minule jsme se zmínili o některých instrukcích provedených či naopak neprovedených na základě nějaké podmínky. Jednalo se o tyto instrukce:
| Instrukce | Stručný popis | 
|---|---|
| B.podmínka návěští | podmíněný skok po splnění podmínky na zadané návěští (kódy podmínek byly uvedeny výše) | 
| CBZ Wn, návěští | pokud platí Wn=0, skok na zadané návěští | 
| CBZ Xn, návěští | pokud platí Xn=0, skok na zadané návěští | 
| CBNZ Wn, návěští | pokud platí Wn≠0, skok na zadané návěští | 
| CBNZ Xn, návěští | pokud platí Xn≠0, skok na zadané návěští | 
Tyto instrukce jsou (ve své variantě s 32bitovými registry) zpětně kompatibilní s instrukcemi známými z 32bitové architektury ARM32.
3. Nové instrukce
Mezi nové instrukce s podmínkou, které lze použít na architektuře AArch64, patří především:
| Instrukce | Význam mnemotechnického kódu | Kapitola | 
|---|---|---|
| CSET | Conditional Set | 4 | 
| CSETM | Conditional Set Mask | 5 | 
| CSEL | Conditional Select | 6 | 
| CSINV | Conditional Select Invert | 7 | 
| CSINC | Conditional Select Increment | 8 | 
| CSNEG | Conditional Select Negate | 9 | 
| CINC | Conditional Increment | 10 | 
| CINV | Conditional Invert | 11 | 
| CNEG | Conditional Negate | 12 | 
| TBZ | Test and Branch if Zero | 13 | 
| TBNZ | Test and Branch if not zero | 13 | 
4. Instrukce CSET – Conditional Set
První novou instrukcí, s níž se dnes seznámíme, je instrukce nazvaná CSET neboli Conditional Set. Tato instrukce vlastně přímo odpovídá požadavkům kladeným na datový typ boolean v mnoha programovacích jazycích, v nichž je hodnota true interně reprezentována jedničkou a hodnota false nulou. Tato instrukce existuje ve dvou variantách, přičemž první varianta pracuje s 32bitovým a druhá varianta s 64bitovým operandem):
CSET Wd, condition
CSET Xd, condition
Například:
CSET W3, EQ
CSET W4, MI
CSET X5, HI
Tato instrukce pracuje následujícím způsobem – v případě, že je podmínka zapsaná ve druhém operandu cond splněna, uloží se do cílového registru Wd či do registru Xd hodnota 1. Pokud podmínka naopak splněna není, uloží se do registru Wd či Xd hodnota 0:
cíl = condition ? 1 : 0;
Ve skutečnosti se v případě CSET jedná o alias pro instrukci CSINC popsanou dále (podmínka ovšem musí být v tomto případě negována):
CSINC Wd, WZR, WZR, invert(condition)
CSINC Xd, XZR, XZR, invert(condition)
neboli:
cíl = invert(condition) ? 0 : 0+1;
5. Instrukce CSETM – Conditional Set Mask
V některých případech je nutné ukládat pravdivostní hodnoty odlišným způsobem – true bude reprezentováno hodnotou, v níž jsou všechny bity nastaveny na jedničku (v případě celých čísel se znaménkem to odpovídá hodnotě -1), false naopak hodnotou, v níž jsou všechny bity nulové. V tomto případě lze pro nastavení použít instrukci CSETM:
CSETM Wd, condition
CSETM Xd, condition
Ve vyšším programovacím jazyce by bylo možné napsat:
cíl = condition ? -1 : 0;
Poznámka: u 32bitového registru odpovídá -1 hodnotě 0xffff ffff, u 64bitového registru pak hodnotě 0xffff ffff ffff ffff.
Opět se jedná o aliasy, tentokrát ovšem na instrukci CSINV:
CSINV Wd, WZR, WZR, invert(condition)
CSINV Xd, XZR, XZR, invert(condition)
Poznámka: slovo „mask“ v názvu instrukce skutečně poměrně přesně odpovídá jednomu způsobu použití, protože pokud platí true=-1 a false=0, lze s těmito hodnotami provádět logický součin a součet bit po bitu, a to i v případě, kdy je druhým operandem odlišná hodnota.
6. Instrukce CSEL – Conditional Select
Další užitečnou instrukcí s podmínkou je instrukce zapisovaná mnemotechnickým kódem CSEL neboli Conditional Select. I tato instrukce existuje ve dvou variantách – 32bitové a 64bitové:
CSEL Wd, Wn, Wm, condition
CSEL Xd, Xn, Xm, condition
Tato instrukce pracuje následovně: pokud je podmínka splněna, uloží se do cílového registru Wd či Xd hodnota z prvního zdrojového registru Wn nebo Xn. Pokud podmínka splněna není, je do cílového registru Wd/Xd uložena hodnota z druhého zdrojového registru Wm/Xm.
Instrukce CSEL tedy nahrazuje programovou konstrukci typu:
cíl = condition ? zdroj1 : zdroj2;
7. Instrukce CSINV – Conditional Select Invert
Alternativní formou instrukce CSEL je instrukce CSINV neboli Conditional Select Invert:
CSINV Wd, Wn, Wm, condition
CSINV Xd, Xn, Xm, condition
Tato instrukce pracuje následovně: pokud je podmínka splněna, uloží se do cílového registru Wd či Xd hodnota z prvního zdrojového registru Wn nebo Xn. Pokud podmínka splněna není, je do cílového registru Wd/Xd uložena negovaná hodnota přečtená z druhého zdrojového registru Wm/Xm.
Instrukce CSINV tedy nahrazuje programovou konstrukci typu:
cíl = condition ? zdroj1 : ~zdroj2;
Poznámka: znak ~ je používán v programovacím jazyku C a od něj odvozených jazycích pro zápis unárního operátoru negace všech bitů (jedničkový doplněk).
8. Instrukce CSINC – Conditional Select Increment
Zajímavá je instrukce CSINC, která kombinuje možnosti instrukce CINC a CSEL:
CSINC Wd, Wn, Wm, condition
CSINC Xd, Xn, Xm, condition
Tato instrukce provádí následující činnost:
Wd = condition ? Wn : Wm+1;
Xd = condition ? Xn : Xm+1;
Jak jsme si již řekli ve čtvrté kapitole, je touto instrukcí realizována i pseudoinstrukce CSET, a to tehdy, pokud jsou oba zdrojové registry nulové (WZR a XZR). V tomto případě se do cílového registru dosadí 0 či 0+1=1:
CSINC Wd, WZR, WZR, invert(condition)
CSINC Xd, XZR, XZR, invert(condition)
9. Instrukce CSNEG – Conditional Select Negate
Instrukce nazvaná CSNEG se do jisté míry podobá instrukci CSINV, ovšem s tím rozdílem, že se namísto jedničkového doplňku (negace) používá při nesplnění podmínky dvojkový doplněk:
CSNEG Wd, Wn, Wm, condition
CSNEG Xd, Xn, Xm, condition
Tato instrukce pracuje následovně: pokud je podmínka splněna, uloží se do cílového registru Wd či Xd hodnota z prvního zdrojového registru Wn nebo Xn. Pokud podmínka splněna není, je do cílového registru Wd/Xd uložena hodnota přečtená z druhého zdrojového registru Wm/Xm, u které se nejdříve změní znaménko (onen zmíněný dvojkový doplněk).
Tato instrukce tedy nahrazuje programovou konstrukci typu:
cíl = condition ? zdroj1 : -zdroj2;
10. Instrukce CINC – Conditional Increment
Instrukce CINC je aliasem pro instrukci CSINC, ovšem s převrácenou podmínkou a shodnými zdrojovými registry:
CINC Wd, Wn, condition
CINC Xd, Xn, condition
Tato instrukce provádí následující činnost (je zde jen jediný zdrojový registr):
Wd = condition ? Wn+1 : Wn;
Xd = condition ? Xn+1 : Xn;
Použití této instrukce je různé, může se například použít pro realizaci příkazu continue v programovacím jazyku C.
11. Instrukce CINV – Conditional Invert
Podobná instrukce taktéž s jedním zdrojovým registrem se jmenuje CINV:
CINV Wd, Wn, condition
CINV Xd, Xn, condition
Prováděná činnost je následující (tilda znamená negaci bit po bitu):
Wd = condition ? ~Wn : Wn;
Xd = condition ? ~Xn : Xn;
Ve skutečnosti se opět jedná o instrukční alias rozpoznávaný assemblery. V tomto případě lze CINV nahradit instrukcí CSINV s oběma zdrojovými registry totožnými:
CSINV Wd, Wn, Wn, invert(condition)
CSINV Xd, Xn, Xn, invert(condition)
12. Instrukce CNEG – Conditional Negate
Poslední instrukce, přesněji řečeno (opět) instrukční alias se jmenuje CNEG:
CNEG Wd, Wn, condition
CNEG Xd, Xn, condition
Prováděná činnost:
Wd = condition ? -Wn : Wn;
Xd = condition ? -Xn : Xn;
Tento alias lze nahradit za CSNEG s totožnými zdrojovými registry a opačně zapsanou podmínkou:
CSNEG Wd, Wn, Wn, invert(condition)
CSNEG Xd, Xn, Xn, invert(condition)
13. Instrukce TBZ a TBNZ (Test and Branch...)
Poslední dvě instrukce, které si dnes popíšeme, spadají do kategorie podmíněných skoků. Tyto instrukce se jmenují TBZ (Test and Branch if Zero) a TBNZ (Test and Branch if Not Zero). Způsob zápisu těchto instrukcí je následující:
TBZ  Xn, #konstanta, návěští
TBZ  Wn, #konstanta, návěští
TBNZ Xn, #konstanta, návěští
TBNZ Wn, #konstanta, návěští
Konstanta má šířku pouze šest bitů, protože je v ní uložen index bitu pracovního registru, který se testuje na nulu či jedničku (u registrů Wn by stačilo jen pět bitů). V případě instrukce TBZ – pokud je n-tý bit registru Xn/Wn nastavený na nulu, provede se skok, v opačném případě se řízení přenese na další instrukci. V případě instrukce TBNZ je bit testován na nulu. Vzhledem k tomu, že v instrukčním slovu je nutné kromě adresy cíle (návěští) specifikovat i číslo pracovního registru a index bitu, je tento typ skoku omezen na rozsah ±32kB, což by ovšem v praxi mělo být více než dostačující (v opačném případě lze TBZ/TBNZ zkombinovat s absolutním skokem B).
14. Odkazy na Internetu
- Cortex-A35
 https://www.arm.com/products/processors/cortex-a/cortex-a35-processor.php
- Cortex-A53
 https://www.arm.com/products/processors/cortex-a/cortex-a53-processor.php
- Cortex-A57
 https://www.arm.com/products/processors/cortex-a/cortex-a57-processor.php
- Cortex-A72
 https://www.arm.com/products/processors/cortex-a/cortex-a72-processor.php
- Cortex-A73
 https://www.arm.com/products/processors/cortex-a/cortex-a73-processor.php
- System cally pro AArch64 na Linuxu
 https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/unistd.h
- Architectures/AArch64 (FedoraProject.org)
 https://fedoraproject.org/wiki/Architectures/AArch64
- SIG pro AArch64 (CentOS)
 https://wiki.centos.org/SpecialInterestGroup/AltArch/AArch64
- The ARMv8 instruction sets
 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch05s01.html
- A64 Instruction Set
 https://developer.arm.com/products/architecture/instruction-sets/a64-instruction-set
- Switching between the instruction sets
 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch05s01.html
- The A64 instruction set
 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch05s01.html
- Introduction to ARMv8 64-bit Architecture
 https://quequero.org/2014/04/introduction-to-arm-architecture/
- MCU market turns to 32-bits and ARM
 http://www.eetimes.com/document.asp?doc_id=1280803
- Cortex-M0 Processor (ARM Holdings)
 http://www.arm.com/products/processors/cortex-m/cortex-m0.php
- Cortex-M0+ Processor (ARM Holdings)
 http://www.arm.com/products/processors/cortex-m/cortex-m0plus.php
- ARM Processors in a Mixed Signal World
 http://www.eeweb.com/blog/arm/arm-processors-in-a-mixed-signal-world
- ARM Architecture (Wikipedia)
 https://en.wikipedia.org/wiki/ARM_architecture
- ARM Documentation: B, BL, BX, BLX, and BXJ
 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204j/Cihfddaf.html
- Branch and Call Sequences Explained
 https://community.arm.com/groups/processors/blog/2013/09/25/branch-and-call-sequences-explained
- Improving ARM Code Density and Performance
 New Thumb Extensions to the ARM Architecture Richard Phelan
- Aarch64 Register and Instruction Quick Start
 https://wiki.cdot.senecacollege.ca/wiki/Aarch64_Register_and_Instruction_Quick_Start
- Exploring AArch64 assembler – Chapter 1
 http://thinkingeek.com/2016/10/08/exploring-aarch64-assembler-chapter1/
- Exploring AArch64 assembler – Chapter 2
 http://thinkingeek.com/2016/10/08/exploring-aarch64-assembler-chapter-2/
- The ARM Processor Architecture
 http://www.arm.com/products/processors/technologies/instruction-set-architectures.php
- Thumb-2 instruction set
 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344c/Beiiegaf.html
- Introduction to ARM thumb
 http://www.eetimes.com/discussion/other/4024632/Introduction-to-ARM-thumb
- ARM, Thumb, and ThumbEE instruction sets
 http://www.keil.com/support/man/docs/armasm/armasm_CEGBEIJB.htm
- An Introduction to ARM Assembly Language
 http://dev.emcelettronica.com/introduction-to-arm-assembly-language
- Processors - ARM
 http://www.arm.com/products/processors/index.php
- The ARM Instruction Set
 http://simplemachines.it/doc/arm_inst.pdf
- ARM Architecture (Wikipedia)
 http://en.wikipedia.org/wiki/ARM_architecture
- C Functions Without Arguments
 https://eklitzke.org/c-functions-without-arguments
- GNU Assembler Examples
 http://cs.lmu.edu/~ray/notes/gasexamples/
- Simply FPU
 http://www.website.masmforum.com/tutorials/fptute/
- Art of Assembly language programming: The 80x87 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_id_100.html
- x86 Instruction Set Reference: FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ
 http://x86.renejeschke.de/html/file_module_x86_id_101.html
- x86 Instruction Set Reference: FLD
 http://x86.renejeschke.de/html/file_module_x86_id_100.html
- x86 Instruction Set Reference: FST/FSTP
 http://x86.renejeschke.de/html/file_module_x86_id_117.html
- x86 Instruction Set Reference: BTC
 http://x86.renejeschke.de/html/file_module_x86_id_23.html
- x86 Instruction Set Reference: BTR
 http://x86.renejeschke.de/html/file_module_x86_id_24.html
- x86 Instruction Set Reference: BTS
 http://x86.renejeschke.de/html/file_module_x86_id_25.html
- x86 Instruction Set Reference: BSF
 http://x86.renejeschke.de/html/file_module_x86_id_19.html
- x86 Instruction Set Reference: BSR
 http://x86.renejeschke.de/html/file_module_x86_id_20.html
- x86 Instruction Set Reference: BSWAP
 http://x86.renejeschke.de/html/file_module_x86_id_21.html
- x86 Instruction Set Reference: XCHG
 http://x86.renejeschke.de/html/file_module_x86_id_328.html
- x86 Instruction Set Reference: SETcc
 http://x86.renejeschke.de/html/file_module_x86_id_288.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
