Ve všech předchozích částech tohoto seriálu jsme se zabývali především psaním programového kódu pro mikroprocesory s architekturami x86, x86-64 a 32bitovou architekturou ARM. Ovšem stále častěji se můžeme setkat se zařízeními, v nichž je použit nějaký mikroprocesor s architekturou AArch64, tedy se 64bitovým ARMem. Právě této architektuře, která je samozřejmě podporována i Fedorou, se budeme poněkud podrobněji věnovat v dnešním článku.

Obsah

1. Použití assembleru v Linuxu: RISCová architektura AArch64

2. Důvody pro vznik architektury AArch64

3. Rodina ARMv8-A

4. Architektura AArch64 z pohledu programátora

5. Pracovní registry

6. Význam třicátého druhého registru

7. Operace s 32bitovými a 64bitovými operandy

8. Možnosti adresování

9. Zjednodušení instrukční sady

10. První demonstrační příklad – šablona pro AArch64

11. Disassemblovaný objektový kód prvního příkladu

12. Druhý demonstrační příklad – tisk řetězce na standardní výstup

13. Disassemblovaný objektový kód druhého příkladu

14. Odkazy na Internetu

1. Použití assembleru v Linuxu: RISCová architektura AArch64

V poměrně velkém množství moderních elektronických zařízení se můžeme setkat s mikroprocesory založenými na 64bitové architektuře AArch64. Tato architektura je sice do jisté míry odvozena od původní „klasické“ 32bitové RISCové architektury ARM (dnes pro odlišení nazývané ARM32), ovšem při přechodu na 64bitový systém došlo k mnoha podstatným změnám, které se týkají jak počtu a funkce pracovních registrů, tak i instrukční sady, která se v některých ohledech od původní RISCové sady odlišuje. Vzhledem k tomu, že architektura AArch64 je dnes podporována mj. i Fedorou (vlastně se jedná o druhý primární systém, ihned po čipech x86-64), zaslouží si podrobnější popis. Nejprve si řekneme, s jakými rozdíly je nutné počítat při práci v assembleru a následně si postupně převedeme jednotlivé demonstrační příklady, s nimiž jsme se již setkali, do 64bitové podoby.

Mikroprocesory a mikrořadiče ARM za sebou mají dlouhou dobu vývoje, takže není divu, že postupně vznikaly různé generace těchto čipů, které se od sebe odlišovaly jak svým výpočetním výkonem, tak i různými změnami v instrukční sadě, uspořádáním cache, počtem řezů (pipeline), použitými submoduly (hardwarová násobička, dělička, jednotka pro SIMD operace, matematický koprocesor) atd. Čipy ARM je možné rozlišit podle architektury, přičemž základní dělení je naznačeno v následující tabulce:

# Architektura Adresová/datová sběrnice Jádro Poznámka/profil (u Cortex)
1 ARMv1 26/32 bitů ARM1 první implementace, technologické demo
2 ARMv2 26/32 bitů ARM2, ARM3 přidána HW násobička a MMU
3 ARMv3 26/32 bitů ARM6, ARM7
4 ARMv4 26/32 bitů ARM8 patří sem mj. i řada čipů StrongARM
5 ARMv5 32 bitů ARM7EJ, ARM9E, ARM10E lze najít ve starších zařízeních
6 ARMv6 32 bitů ARM11 dodnes používaná jádra
7 ARMv6-M 32 bitů Cortex-M0, Cortex-M0+, Cortex-M1 mikrořadiče (M v názvu)
8 ARMv7-M 32 bitů Cortex-M3 mikrořadiče (poznáme podle M v názvu)
9 ARMv7E-M 32 bitů Cortex-M4, Cortex-M7 mikrořadiče (M v názvu)
10 ARMv7-R 32 bitů Cortex-R4, Cortex-R5, Cortex-R7 realtime aplikace (R v názvu)
11 ARMv7-A 32 bitů Cortex-A5, Cortex-A7, Cortex-A8, Cortex-A9, Cortex-A12, Cortex-A15, Cortex-A17 smartphony atd.
12 ARMv8-A 32/64 bitů Cortex-A35, Cortex-A53, A57, A72 a A73 smartphony atd.

V dalším textu nás budou zajímat především čipy s architekturou ARMv8-A, která je vypsána na posledním řádku tabulky.

2. Důvody pro vznik architektury AArch64

Existuje hned několik důvodů, proč se společnost ARM Holdings rozhodla k poměrně rizikovému a velmi pravděpodobně i finančně náročnému kroku, tj. k vývoji zcela nové a zpětně nekompatibilní architektury. Mikroprocesory ARM se totiž začaly používat v nových oblastech, například pro některé servery, kde již možnosti 32bitových adres nemusely být dostačující. Navíc původní 32bitová architektura začala vykazovat určité známky zastaralosti, což pravděpodobně není až tak překvapivé, zvláště když si uvědomíme, že první RISCové ARMy začaly být testovány již v roce 1985, tj. před 31 roky. Bylo tedy jen logické, že se vylepšení původní architektury a současně přechod na 64bitovou aritmeticko-logickou jednotku a adresování, provede v jednom kroku a současně se zachová původní portfolia mikroprocesorů a mikrořadičů. Nová architektura i s ní spojená instrukční sada byly navrženy s ohledem na moderní překladače a virtuální stroje. Společnost ARM se v tomto ohledu mohla opřít o mnohaleté studium chování existujících aplikací (ostatně právě na základě tohoto studia byly v minulosti vytvořeny instrukční sady Thumb a Thumb-2).

3. Rodina ARMv8-A

V současnosti používané 64bitové čipy ARM patří do rodiny ARMv8-A. Nalezneme zde jádra Cortex-A35, Cortex-A53, Cortex-A57, Cortex-A72 a Cortex-A73, které se od sebe odlišují především výpočetním výkonem. Čipy s těmito jádry lze nalézt ve výkonných tabletech, ale i serverech. Vzhledem k tomu, že u ARMv8-A je zaručena zpětná kompatibilita s existující 32bitovou architekturou ARMv7-A, znamená to, že mikroprocesory je možné přepnout mezi 32bitovým kompatibilním režimem a plnohodnotným 64bitovým režimem (ve skutečnosti se v 32bitovém režimu je možné provést přepnutí mezi A32 a T32, tj. mezi původními RISCovými instrukcemi a instrukcemi Thumb/Thumb2).

4. Architektura AArch64 z pohledu programátora

Z pohledu programátora pracujícího v assembleru je architektura AArch64 v několika ohledech odlišná od původní 32bitové architektury. Především se zvýšil počet pracovních registrů z patnácti na 31. Všechny registry se navíc rozšířily z třiceti dvou bitů na 64 bitů. Ovšem mnohé operace stále podporují i 32bitové operandy – v tomto případě se použije ta samá skupina registrů, z nichž se ovšem využije jen spodních 32 bitů (nedochází zde tedy k rozdvojení každého 64bitového registru na dva registry 32bitové, jak to známe z jiných typů procesorů). Podporován je i matematický koprocesor, jehož struktura se v mnoha ohledech blíží VPS. Nesmíme zapomenout ani na změny v instrukční sadě, které budou popsány níže. Poslední důležitým vylepšením je „zadrátování“ podpory pro AES, SHA-1 a SHA-256, což je využitelné jak na tabletech či smartphonech, tak i na serverech (o podrobnostech se zmíníme v dalších částech tohoto seriálu).

Zajímavé je, že se designéři AArch64 vrátili k původní myšlence RISC a i z tohoto důvodu mají všechny instrukce konstantní šířku třiceti dvou bitů (na rozdíl od Thumb a Thumb-2).

5. Pracovní registry

Původních patnáct pracovních registrů pojmenovaných R0R14 bylo rozšířeno na 31 registrů, z nichž každý má šířku 64 bitů. Z tohoto důvodu muselo dojít k úpravě pojmenování registrů způsobem, který je naznačený v následující tabulce:

Jméno Význam
r0..r30 použito například v dokumentaci, popisu ABI atd.
x0..x30 celý 64bitový registr použitý jako zdroj či cíl
w0..w30 spodních 32 bitů registru (horních 32 bitů výsledku je buď vynulováno nebo znaménkově rozšířeno)

Všechny tyto registry mají v instrukční sadě stejné postavení, na rozdíl od instrukční sady Thumb, v níž se pro některé instrukce může použít jen spodních osm registrů.

6. Význam třicátého druhého registru

Třicátý druhý registr, tj. registr se jménem x31 či w31, není ve skutečnosti běžným pracovním registrem, protože má dva speciální významy. V případě použití tohoto registru v aritmetických či logických instrukcích se při použití ve funkci vstupního operandu tento registr chová jako konstantní nula a při použití ve funkci operandu výstupního jako /dev/null (výsledek se zahodí a neovlivní skutečnou hodnotu uloženou do registru). Proto se v assembleru může pro pojmenování tohoto registru použít jméno xzr či wzr. U instrukcí pracujících se zásobníkem se tento registr chová jako ukazatel na vrchol zásobníku a proto se pro něj v assembleru používá jméno rsp či jen SP (na velikosti písmen u jmen registrů samozřejmě nezáleží).

Poznámky:

  1. Registr x30 se používá ve funkci LR (Link Register).
  2. Registr PC není přímo dostupný.

7. Operace s 32bitovými a 64bitovými operandy

U aritmetických instrukcí je možné zvolit, zda se mají operace provádět s 32bitovými či 64bitovými operandy. U 64bitových operandů je vlastní provedení instrukce jednoduché, ovšem u 32bitových operandů je nutné zajistit, aby měl výsledek operace smysl i ve chvíli, kdy se převede na 64 bitů. Z tohoto důvodu je při použití 32bitového zdrojového operandu horních 32 bitů původně 64bitového registru ignorováno a při použití 32bitového cílového operandu se horních 32 bitů buď vynuluje (většina instrukcí) či znaménkově rozšíří. U 32bitových operací se navíc příznaky (zero, carry, negative…) nastavují pouze na základě 32bitového výsledku. Některé výjimky, které se týkají například bitových posunů a rotací, si popíšeme u jednotlivých demonstračních příkladů, kde se tyto instrukce použijí.

8. Možnosti adresování

Díky použití pracovních registrů se šířkou 64 bitů se samozřejmě dosti podstatným způsobem rozšířil adresní prostor, který by jinak byl omezen na „pouhých“ 32 bitů. Teoretický adresový rozsah 64 bitů je u architektury AArch64 ve skutečnosti snížen na 49 bitů virtuální adresy, což je však podle všeho dostačující, a to i pro relativně vzdálenou budoucnost. Navíc se horních osm bitů adresy ignoruje, což znamená, že do této oblasti registru použitého pro adresování je možné uložit „tag“. Tato technika se v některých programovacích jazycích používá pro rozlišení datového typu (příkladem mohou být jazyky odvozené od LISPu).

Některé další omezení je způsobeno tím, že všechny instrukce mají konstantní šířku 32 bitů:

  • Pro podmíněné skoky může cíl skoku ležet v rozsahu ±1 MB
  • Pro relativní skoky může cíl opět ležet v rozsahu ±1 MB
  • U nepodmíněných skoků je rozsah větší, celých ±128 MB (což by mělo dostačovat pro prakticky všechny účely)
  • Generování adresy (ukládané do registru) lze implementovat dvojicí instrukcí pro rozsah 4GB

9. Zjednodušení instrukční sady

Instrukční sada AArch64 se oproti původní 32bitové RISCové sadě v několika ohledech liší, především pak v následujících oblastech:

  1. Byly odstraněny instrukce LDM, STM, PUSH a POP ve variantě s bitovým polem registru
  2. Naproti tomu lze použít instrukce LDP a STP pracující s libovolnými dvěma registry (zajímavá myšlenka na využití 32bitového slova)
  3. Byly odstraněny prefixy pro podmínku, nyní jsou podmínky použity jen u skoků a několika dalších vybraných instrukcí
  4. Byl odstraněn prefix IT známý z Thumb-2

Tyto změny jsou založeny na výsledcích benchmarků, protože současné prediktory skoků jsou již velmi kvalitní. Navíc odstranění podmínkových bitů umožnilo použití více bitů v instrukčním slově pro jiné účely.

10. První demonstrační příklad – šablona pro AArch64

Podívejme se nyní na velmi jednoduchý demonstrační příklad. Jedná se o šablonu, kterou jsme si již ukázali pro jiné architektury (x86, PowerPC, s390, 32bitový ARM):

# asmsyntax=as

# Sablona pro zdrojovy kod Linuxoveho programu naprogramovaneho
# v assembleru GNU AS pro architekturu AArch64.
#
# Autor: Pavel Tisnovsky



# Linux kernel system call table
sys_exit=93



#-----------------------------------------------------------------------------
.section .data



#-----------------------------------------------------------------------------
.section .bss



#-----------------------------------------------------------------------------
.section .text
        .global _start          // tento symbol ma byt dostupny i z linkeru

_start:
        mov  x8, #sys_exit      // cislo sycallu pro funkci "exit"
        mov  x0, #0             // exit code = 0
        svc  0                  // volani Linuxoveho kernelu

Pro porovnání si ukažme stejný příklad, ovšem pro ARM 32:

# asmsyntax=as

# Sablona pro zdrojovy kod Linuxoveho programu naprogramovaneho
# v assembleru GNU AS.
#
# Autor: Pavel Tisnovsky



# Linux kernel system call table
sys_exit=1



#-----------------------------------------------------------------------------
.section .data



#-----------------------------------------------------------------------------
.section .bss



#-----------------------------------------------------------------------------
.section .text
        .global _start          @ tento symbol ma byt dostupny i z linkeru

_start:
        mov   r7,$sys_exit      @ cislo sycallu pro funkci "exit"
        mov   r0,#0             @ exit code = 0
        svc   0                 @ volani Linuxoveho kernelu

Změny, které musely být provedeny, jsou následující:

  1. U AArch64 se poznámky zapisují „logicky“ pomocí znaků //
  2. Namísto 32bitových registrů r0r14 se používají registry x0x30
  3. Číslo syscallu se ukládá do registru x8, nikoli do r7 (pomůcka: ARMv8 – x8, ARMv7 – r7)
  4. Čísla syscallů jsou na AArch64 zcela odlišná!

11. Disassemblovaný objektový kód prvního příkladu

Náš demonstrační příklad přeložíme a slinkujeme následujícím způsobem:

as aarch64.s -o aarch64.o
ld -s aarch64.o

Pro zajímavost se podívejme na obsah vytvořeného spustitelného binárního souboru a.out. Tento obsah získáme příkazem:

objdump -f -d -t -h a.out
a.out:     file format elf64-littleaarch64
architecture: aarch64, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x0000000000400078

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         0000000c  0000000000400078  0000000000400078  00000078  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
SYMBOL TABLE:
no symbols



Disassembly of section .text:

0000000000400078 <.text>:
  400078:       d2800ba8        mov     x8, #0x5d                       // #93
  40007c:       d2800000        mov     x0, #0x0                        // #0
  400080:       d4000001        svc     #0x0

Povšimněte si, že všechny instrukce mají skutečně konstantní šířku 32 bitů. Navíc je zajímavé, že obě instrukce mov pracují se skutečnými konstantami uloženými přímo v instrukčním slově.

12. Druhý demonstrační příklad – tisk řetězce na standardní výstup

Druhý demonstrační příklad je nepatrně složitější, protože se jedná o aplikaci typu Hello world, v níž musíme volat dvě funkce jádra – sys_write pro zápis na standardní výstup a sys_exit pro ukončení aplikace. Opět si povšimněte, že se čísla syscallů zcela odlišují od hodnot, s nimiž jsme se až doposud setkali:

# asmsyntax=as

# Jednoducha aplikace typu "Hello world!" naprogramovana
# v assembleru GNU as.
#
# Autor: Pavel Tisnovsky



# Linux kernel system call table
sys_exit=93
sys_write=64



#-----------------------------------------------------------------------------
.section .data

hello_lbl:
        .string "Hello World!\n"

#-----------------------------------------------------------------------------
.section .bss



#-----------------------------------------------------------------------------
.section .text
        .global _start          // tento symbol ma byt dostupny i linkeru

_start:
        mov  x8, #sys_write     // cislo sycallu pro funkci "write"
        mov  x0, #1             // standardni vystup
        ldr  x1, =hello_lbl     // adresa retezce, ktery se ma vytisknout
        mov  x2, #13            // pocet znaku, ktere se maji vytisknout
        svc  0                  // volani Linuxoveho kernelu

        mov  x8, #sys_exit      // cislo sycallu pro funkci "exit"
        mov  x0, #0             // exit code = 0
        svc  0                  // volani Linuxoveho kernelu

Za povšimnutí stojí použití pseudoinstrukce ldr pro načtení adresy počátečního znaku v řetězci.

13. Disassemblovaný objektový kód druhého příkladu

Opět se podívejme na způsob překladu druhého demonstračního příkladu do strojového kódu. Poznámky budou uvedeny pod výpisem zdrojového kódu:

a.out:     file format elf64-littleaarch64
architecture: aarch64, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x00000000004000b0

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000028  00000000004000b0  00000000004000b0  000000b0  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         0000000e  00000000004100d8  00000000004100d8  000000d8  2**0
                  CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
no symbols



Disassembly of section .text:

00000000004000b0 <.text>:
  4000b0:       d2800808        mov     x8, #0x40                       // #64
  4000b4:       d2800020        mov     x0, #0x1                        // #1
  4000b8:       580000c1        ldr     x1, 0x4000d0
  4000bc:       d28001a2        mov     x2, #0xd                        // #13
  4000c0:       d4000001        svc     #0x0
  4000c4:       d2800ba8        mov     x8, #0x5d                       // #93
  4000c8:       d2800000        mov     x0, #0x0                        // #0
  4000cc:       d4000001        svc     #0x0
  4000d0:       004100d8        .inst   0x004100d8 ; undefined
  4000d4:       00000000        .inst   0x00000000 ; undefined

Jediná instrukce, která se přeložila složitějším způsobem, je instrukce ldr. Ta načítá konstantu uloženou od adresy 4000d0. Tato adresa je 64 bitová, proto je rozepsána na dva řádky:

  4000d0:       004100d8        .inst   0x004100d8 ; undefined
  4000d4:       00000000        .inst   0x00000000 ; undefined

Po složení obou 32bitových slov získáme adresu 0x0000_0000_0041_00d8 ukazující přesně na začátek datové sekce, v níž je uložen řetězec „Hello world!\n“:

  1 .data         0000000e  00000000004100d8  00000000004100d8  000000d8  2**0
                  CONTENTS, ALLOC, LOAD, DATA

14. Odkazy na Internetu

  1. Cortex-A35
    https://www.arm.com/products/processors/cortex-a/cortex-a35-processor.php
  2. Cortex-A53
    https://www.arm.com/products/processors/cortex-a/cortex-a53-processor.php
  3. Cortex-A57
    https://www.arm.com/products/processors/cortex-a/cortex-a57-processor.php
  4. Cortex-A72
    https://www.arm.com/products/processors/cortex-a/cortex-a72-processor.php
  5. Cortex-A73
    https://www.arm.com/products/processors/cortex-a/cortex-a73-processor.php
  6. System cally pro AArch64 na Linuxu
    https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/unistd.h
  7. Architectures/AArch64 (FedoraProject.org)
    https://fedoraproject.org/wiki/Architectures/AArch64
  8. SIG pro AArch64 (CentOS)
    https://wiki.centos.org/SpecialInterestGroup/AltArch/AArch64
  9. The ARMv8 instruction sets
    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch05s01.html
  10. A64 Instruction Set
    https://developer.arm.com/products/architecture/instruction-sets/a64-instruction-set
  11. Switching between the instruction sets
    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch05s01.html
  12. The A64 instruction set
    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch05s01.html
  13. Introduction to ARMv8 64-bit Architecture
    https://quequero.org/2014/04/introduction-to-arm-architecture/
  14. MCU market turns to 32-bits and ARM
    http://www.eetimes.com/document.asp?doc_id=1280803
  15. Cortex-M0 Processor (ARM Holdings)
    http://www.arm.com/products/processors/cortex-m/cortex-m0.php
  16. Cortex-M0+ Processor (ARM Holdings)
    http://www.arm.com/products/processors/cortex-m/cortex-m0plus.php
  17. ARM Processors in a Mixed Signal World
    http://www.eeweb.com/blog/arm/arm-processors-in-a-mixed-signal-world
  18. ARM Architecture (Wikipedia)
    https://en.wikipedia.org/wiki/ARM_architecture
  19. ARM Documentation: B, BL, BX, BLX, and BXJ
    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204j/Cihfddaf.html
  20. Branch and Call Sequences Explained
    https://community.arm.com/groups/processors/blog/2013/09/25/branch-and-call-sequences-explained
  21. Improving ARM Code Density and Performance
    New Thumb Extensions to the ARM Architecture Richard Phelan
  22. Aarch64 Register and Instruction Quick Start
    https://wiki.cdot.senecacollege.ca/wiki/Aarch64_Register_and_Instruction_Quick_Start
  23. Exploring AArch64 assembler – Chapter 1
    http://thinkingeek.com/2016/10/08/exploring-aarch64-assembler-chapter1/
  24. Exploring AArch64 assembler – Chapter 2
    http://thinkingeek.com/2016/10/08/exploring-aarch64-assembler-chapter-2/
  25. The ARM Processor Architecture
    http://www.arm.com/products/processors/technologies/instruction-set-architectures.php
  26. Thumb-2 instruction set
    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344c/Beiiegaf.html
  27. Introduction to ARM thumb
    http://www.eetimes.com/discussion/other/4024632/Introduction-to-ARM-thumb
  28. ARM, Thumb, and ThumbEE instruction sets
    http://www.keil.com/support/man/docs/armasm/armasm_CEGBEIJB.htm
  29. An Introduction to ARM Assembly Language
    http://dev.emcelettronica.com/introduction-to-arm-assembly-language
  30. Processors – ARM
    http://www.arm.com/products/processors/index.php
  31. The ARM Instruction Set
    http://simplemachines.it/doc/arm_inst.pdf
  32. ARM Architecture (Wikipedia)
    http://en.wikipedia.org/wiki/ARM_architecture
  33. C Functions Without Arguments
    https://eklitzke.org/c-functions-without-arguments
  34. GNU Assembler Examples
    http://cs.lmu.edu/~ray/notes/gasexamples/
  35. Simply FPU
    http://www.website.masmforum.com/tutorials/fptute/
  36. Art of Assembly language programming: The 80×87 Floating Point Coprocessors
    https://courses.engr.illinois.edu/ece390/books/artofasm/CH14/CH14-3.html
  37. Art of Assembly language programming: The FPU Instruction Set
    https://courses.engr.illinois.edu/ece390/books/artofasm/CH14/CH14-4.html
  38. INTEL 80387 PROGRAMMER’S REFERENCE MANUAL
    http://www.ragestorm.net/downloads/387intel.txt
  39. x86 Instruction Set Reference: FLD
    http://x86.renejeschke.de/html/file_module_x86_id_100.html
  40. x86 Instruction Set Reference: FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ
    http://x86.renejeschke.de/html/file_module_x86_id_101.html
  41. x86 Instruction Set Reference: FLD
    http://x86.renejeschke.de/html/file_module_x86_id_100.html
  42. x86 Instruction Set Reference: FST/FSTP
    http://x86.renejeschke.de/html/file_module_x86_id_117.html
  43. x86 Instruction Set Reference: BTC
    http://x86.renejeschke.de/html/file_module_x86_id_23.html
  44. x86 Instruction Set Reference: BTR
    http://x86.renejeschke.de/html/file_module_x86_id_24.html
  45. x86 Instruction Set Reference: BTS
    http://x86.renejeschke.de/html/file_module_x86_id_25.html
  46. x86 Instruction Set Reference: BSF
    http://x86.renejeschke.de/html/file_module_x86_id_19.html
  47. x86 Instruction Set Reference: BSR
    http://x86.renejeschke.de/html/file_module_x86_id_20.html
  48. x86 Instruction Set Reference: BSWAP
    http://x86.renejeschke.de/html/file_module_x86_id_21.html
  49. x86 Instruction Set Reference: XCHG
    http://x86.renejeschke.de/html/file_module_x86_id_328.html
  50. x86 Instruction Set Reference: SETcc
    http://x86.renejeschke.de/html/file_module_x86_id_288.html
  51. X86 Assembly/Arithmetic
    https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic
  52. Art of Assembly – Arithmetic Instructions
    http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-2.html
  53. The GNU Assembler Tutorial
    http://tigcc.ticalc.org/doc/gnuasm.html
  54. The GNU Assembler – macros
    http://tigcc.ticalc.org/doc/gnuasm.html#SEC109
  55. ARM subroutines & program stack
    http://www.toves.org/books/armsub/
  56. Generating Mixed Source and Assembly List using GCC
    http://www.systutorials.com/240/generate-a-mixed-source-and-assembly-listing-using-gcc/
  57. Calling subroutines
    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0100a/armasm_cihcfigg.htm
  58. ARM Assembly Language Programming
    http://peter-cockerell.net/aalp/html/frames.html
  59. ASM Flags
    http://www.cavestory.org/guides/csasm/guide/asm_flags.html
  60. Status Register
    https://en.wikipedia.org/wiki/Status_register
  61. Intel x86 JUMP quick reference
    http://unixwiz.net/techtips/x86-jumps.html
  62. Linux assemblers: A comparison of GAS and NASM
    http://www.ibm.com/developerworks/library/l-gas-nasm/index.html
  63. Programovani v assembleru na OS Linux
    http://www.cs.vsb.cz/grygarek/asm/asmlinux.html
  64. Is it worthwhile to learn x86 assembly language today?
    https://www.quora.com/Is-it-worthwhile-to-learn-x86-assembly-language-today?share=1
  65. Why Learn Assembly Language?
    http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language
  66. Is Assembly still relevant?
    http://programmers.stackexchange.com/questions/95836/is-assembly-still-relevant
  67. Why Learning Assembly Language Is Still a Good Idea
    http://www.onlamp.com/pub/a/onlamp/2004/05/06/writegreatcode.html
  68. Assembly language today
    http://beust.com/weblog/2004/06/23/assembly-language-today/
  69. Assembler: Význam assembleru dnes
    http://www.builder.cz/rubriky/assembler/vyznam-assembleru-dnes-155960cz
  70. Assembler pod Linuxem
    http://phoenix.inf.upol.cz/linux/prog/asm.html
  71. AT&T Syntax versus Intel Syntax
    https://www.sourceware.org/binutils/docs-2.12/as.info/i386-Syntax.html
  72. Linux Assembly website
    http://asm.sourceforge.net/
  73. Using Assembly Language in Linux
    http://asm.sourceforge.net/articles/linasm.html
  74. vasm
    http://sun.hasenbraten.de/vasm/
  75. vasm – dokumentace
    http://sun.hasenbraten.de/vasm/release/vasm.html
  76. The Yasm Modular Assembler Project
    http://yasm.tortall.net/
  77. 680×0:AsmOne
    http://www.amigacoding.com/index.php/680×0:AsmOne
  78. ASM-One Macro Assembler
    http://en.wikipedia.org/wiki/ASM-One_Macro_Assembler
  79. ASM-One pages
    http://www.theflamearrows.info/documents/asmone.html
  80. Základní informace o ASM-One
    http://www.theflamearrows.info/documents/asminfo.html
  81. Linux Syscall Reference
    http://syscalls.kernelgrok.com/
  82. Programming from the Ground Up Book – Summary
    http://savannah.nongnu.org/projects/pgubook/
  83. IBM System 360/370 Compiler and Historical Documentation
    http://www.edelweb.fr/Simula/
  84. IBM 700/7000 series
    http://en.wikipedia.org/wiki/IBM_700/7000_series
  85. IBM System/360
    http://en.wikipedia.org/wiki/IBM_System/360
  86. IBM System/370
    http://en.wikipedia.org/wiki/IBM_System/370
  87. Mainframe family tree and chronology
    http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_FT1.html
  88. 704 Data Processing System
    http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_PP704.html
  89. 705 Data Processing System
    http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_PP705.html
  90. The IBM 704
    http://www.columbia.edu/acis/history/704.html
  91. IBM Mainframe album
    http://www-03.ibm.com/ibm/history/exhibits/mainframe/mainframe_album.html
  92. Osmibitové muzeum
    http://osmi.tarbik.com/
  93. Tesla PMI-80
    http://osmi.tarbik.com/cssr/pmi80.html
  94. PMI-80
    http://en.wikipedia.org/wiki/PMI-80
  95. PMI-80
    http://www.old-computers.com/museum/computer.asp?st=1&c=1016
  96. The 6502 overflow flag explained mathematically
    http://www.righto.com/2012/12/the-6502-overflow-flag-explained.html
  97. X86 Opcode and Instruction Reference
    http://ref.x86asm.net/coder32.html