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
4. Architektura AArch64 z pohledu programátora
6. Význam třicátého druhého registru
7. Operace s 32bitovými a 64bitovými operandy
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
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 R0 až R14 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:
- Registr x30 se používá ve funkci LR (Link Register).
- 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:
- Byly odstraněny instrukce LDM, STM, PUSH a POP ve variantě s bitovým polem registru
- 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)
- Byly odstraněny prefixy pro podmínku, nyní jsou podmínky použity jen u skoků a několika dalších vybraných instrukcí
- 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í:
- U AArch64 se poznámky zapisují „logicky“ pomocí znaků //
- Namísto 32bitových registrů r0 až r14 se používají registry x0 až x30
- Číslo syscallu se ukládá do registru x8, nikoli do r7 (pomůcka: ARMv8 - x8, ARMv7 - r7)
- Čí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
- 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