Obsah
1. Rodina mikroprocesorů a mikrořadičů H8 (2.část – řada 300H)
2. Nejmarkantnější rozdíly mezi řadami 300, 300L a 300H
4. Programový čítač (PC) a ukazatel na vrchol zásobníku (SP)
5. Stavový a řídicí registr (CCR)
7. Změny provedené v instrukční sadě
8. Instrukce nově podporující šestnáctibitové operandy
9. Instrukce nově podporující 32bitové operandy
10. Nové aritmetické instrukce
11. Rozšíření sémantiky instrukce EEPMOV
12. Další moduly, které lze nalézt na mikrořadiči
1. Rodina mikroprocesorů a mikrořadičů H8 (2.část – řada 300H)
V předchozí části „nekonečného“ seriálu Co se děje v počítači jsme se seznámili s mikroprocesorovými a mikrořadičovými jádry H8/300 a H8/300L. Připomeňme si, že se v obou případech jedná o osmibitová jádra, přičemž ovšem ve skutečnosti některé instrukce dokážou pracovat i se šestnáctibitovými operandy. Osmibitové mikrořadiče se v současnosti stále používají a v některých oblastech se s velkou pravděpodobností budou používat i nadále, protože pořád existují požadavky na sice málo výkonný, ale levný čip s malou spotřebou (ostatně i v amatérské oblasti se tyto čipy prosadily, viz například populární Arduino). Ovšem ve chvíli, kdy se začínají tvořit rozsáhlejší aplikace (či řídicí systémy), poměrně brzy narazíme na některé limity osmibitových mikrořadičů – ať již se to týká jejich výpočetního výkonu (což nemusí být tak kritické), tak i maximální kapacity adresovatelné paměti (typicky max. 64 kB). A právě z těchto důvodů nalezneme v rodině H8 i poněkud výkonnější jádra H8/300H.
Na následujícím obrázku je naznačen postupný vývoj mikroprocesorů a mikrořadičů patřících do rodiny H8. Svůj původ mají tyto čipy v osmibitovém jádru H8/300 (bez dalšího písmena na konci). Z tohoto jádra se vyvinulo taktéž osmibitové jádro H8/300L a 16/32bitové jádro H8/300H. Dalším odvozením vznikla jádra H8S, která jsou rychlejší a nalezneme u nich větší množství přídavných modulů, například více čítačů/časovačů, programovatelný generátor pulsů a zejména pak CAN bus (právě podpora této sběrnice je prakticky nezbytná pro použití čipů H8 ve vozidlech, ovšem CAN dnes nalezneme i v dalších aplikacích).
Obrázek 1: Základní řady mikroprocesorů a mikrořadičů z rodiny H8. Žlutě jsou zvýrazněny osmibitové čipy (s omezeným repertoárem šestnáctibitových operací), zeleně pak čipy šestnáctibitové (s omezeným repertoárem 32bitových operací).
2. Nejmarkantnější rozdíly mezi řadami 300, 300L a 300H
I přes mnoho společných vlastností, které jádra z rodiny H8 sdílí (podobná a zpětně kompatibilní instrukční sada, kódování instrukcí, stavový a řídicí registr atd.) samozřejmě nalezneme mezi osmibitovými jádry H8/300 a H8/300L na straně jedné a H8/300H na straně druhé poměrně velké množství rozdílů. Nejmarkantnější je rozšíření adresového rozsahu, protože u čipů řady H8/300H lze adresovat až šestnáct megabajtů RAM/ROM (tyto změny se projevily i v nabídce adresovacích režimů). Pochopitelně se rozšířily i možnosti aritmeticko-logické jednotky, protože většinu operací je možné provádět s osmibitovými i šestnáctibitovými operandy, některé operace dokonce s operandy o šířce plných 32 bitů. Jak si řekneme hned v navazující kapitole, došlo i k rozšíření množiny pracovních registrů, ke kterým je možné přistupovat různým způsobem (osmibitové páry, 16bitový registr, 32bitový registr). I přes tyto rozdíly je zachována zpětná kompatibilita, takže na jádrech H8/300H lze v případě potřeby spouštět kód původně přeložený pro osmibitová jádra H8.
Poznámka: v případě potřeby ještě výkonnějších čipů již zpětná kompatibilita není zachována, protože řada SuperH má i přes některé podobnosti s H8 odlišnou instrukční sadu.
3. Sada pracovních registrů
Připomeňme si nejdříve, jak vlastně vypadala sada pracovních registrů na osmibitových jádrech H8/300. K dispozici bylo celkem šestnáct osmibitových pracovních registrů rozdělených do dvou skupin RxH a RxL. Vždy dva registry se stejným indexem, tedy například R1H a R1L bylo možné v některých instrukcích použít ve funkci šestnáctibitového registru (zde R1):
8bit registr | 8bit registr | 16bitový pár |
---|---|---|
R0H | R0L | R0 |
R1H | R1L | R1 |
R2H | R2L | R2 |
R3H | R3L | R3 |
R4H | R4L | R4 |
R5H | R5L | R5 |
R6H | R6L | R6 |
R7H | R7L | R7 (též SP) |
U jader H8/300H došlo k důležitému rozšíření, protože k osmibitovým registrům RxH a RxL bylo přidáno dalších osm registrů Ex (x=0..7), z nichž každý má šířku šestnáct bitů. Vždy tři registry se shodným indexem, tedy například E2+R2H+R2L tvoří jeden 32bitový registr nazvaný ER2. Podívejme se na následující tabulku, která vzájemné vztahy mezi pracovními registry možná osvětlí:
16bit registr | 8bit registr | 8bit registr | 16bitový pár | 32bitový registr |
---|---|---|---|---|
E0 | R0H | R0L | R0=R0H+R0L | ER0=E0+R0H+R0L |
E1 | R1H | R1L | R1=R1H+R1L | ER1=E1+R1H+R1L |
E2 | R2H | R2L | R2=R2H+R2L | ER2=E2+R2H+R2L |
E3 | R3H | R3L | R3=R3H+R3L | ER3=E3+R3H+R3L |
E4 | R4H | R4L | R4=R4H+R4L | ER4=E4+R4H+R4L |
E5 | R5H | R5L | R5=R5H+R5L | ER5=E5+R5H+R5L |
E6 | R6H | R6L | R6=R6H+R6L | ER6=E6+R6H+R6L |
E7 | R7H | R7L | R7=R7H+R7L | ER7=E7+R7H+R7L |
Je tedy možné říci, že se počet pracovních registrů zdvojnásobil, protože k dispozici je celkem šestnáct šestnáctibitových registrů: E0..E7 a R0..R7, které lze v případě potřeby v některých instrukcích spojit do 32bitových registrů ER0..ER7 či naopak některé registry rozdělit na osmibitové části R0H..R7H a R0L..R7L.
Poznámka: můžeme zde vidět jistou podobnost s architekturou i386, kde taktéž existuje možnost přistupovat k nejnižším osmi bitům registru EAX přes alias AL, k vyšším osmi bitům přes alias AH a k nižším šestnácti bitům přes alias AX. Ovšem již zde není možné explicitně přistoupit k vyšším 16bitům (něco na způsob AXH) a navíc toto dělení platí pouze pro čtyři pracovní registry EAX, EBX, ECX a EDX.
4. Programový čítač (PC) a ukazatel na vrchol zásobníku (SP)
Tato kapitola bude velmi stručná, protože činnost programového čítače zůstala zachována, pouze se podle očekávání změnila jeho šířka. Původně měl registr PC šířku šestnácti bitů a umožňoval tak adresovat maximálně 64kB RAM+ROM (H8 nemá oddělené prostory pro RAM a ROM), u jader H8/300H i H8S byla šířka registru PC rozšířena na 24 bitů a umožňuje tedy adresovat maximálně 16MB paměti. Ukazatel na vrchol zásobníku je tvořen registrem ER7, ovšem opět platí, že zásobník musí ležet v adresovém rozsahu 16MB, takže by SP měl mít nejvyšších osm bitů vynulovaných (ER7 slouží jako SP pouze u několika instrukcí, jinak ho lze použít jako běžný pracovní registr; zde samozřejmě může být v horních osmi bitech libovolná hodnota).
5. Stavový a řídicí registr (CCR)
Stavový a řídicí registr (Condition Code Register) zůstal prakticky beze změn, takže má stále šířku osmi bitů, což je zde více než dostatečné:
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ | I | U | H | U | N | Z | V | C | +---+---+---+---+---+---+---+---+
Význam jednotlivých bitů stavového a řídicího registru je popsán v následující tabulce:
Index | Příznak | Význam zkratky | Poznámka |
---|---|---|---|
7 | I | interrupt | maskování neboli zákaz IRQ (přerušení) |
6 | U | user bit | bit, který lze nastavit či testovat instrukcemi LDC, STC, ANDC, ORC a XORC |
5 | H | half carry | přenos z bitu číslo 3 do bitu číslo 4 (použit instrukcemi DAA a DAS) |
4 | U | user bit | bit, který lze nastavit či testovat instrukcemi LDC, STC, ANDC, ORC a XORC |
3 | N | negative | výsledek ALU operace je záporný |
2 | Z | zero | výsledek ALU operace je nulový |
1 | V | overflow | přetečení (znaménková aritmetika, signed) |
0 | C | carry | přenos (bezznaménková aritmetika, unsigned) |
6. Adresovací režimy
Změny nastaly v nabídce adresovacích režimů, což je vlastně logické, protože tyto změny velmi úzce souvisí s rozšířením adres z šestnácti bitů na 24 bitů i s rozšířením šířky pracovních registrů. Dostupné adresovací režimy jsou shrnuty v následující tabulce:
Název režimu | Zápis v asm | Význam |
---|---|---|
Register direct | Rn | většina instrukcí akceptuje osmibitový i šestnáctibitový registr |
Register indirect | @ERn | ERn je 32bitový registr obsahující adresu (24 bitů) |
Register indirect with displacement | @(d:16,ERn) | jako předchozí režim, ovšem navíc se 16bitovým offsetem |
Register indirect with displacement | @(d:24,ERn) | jako předchozí režim, ovšem navíc s 24bitovým offsetem |
Register indirect with post-increment | @ERn+ | pro instrukce MOV, posun o jeden, dva či čtyři bajty podle typu přenosu |
Register indirect with pre-decrement | @-ERn | pro instrukce MOV, posun o jeden, dva či čtyři bajty podle typu přenosu |
Absolute address | @aa:8 | za instrukcí následuje osmibitová konstanta, přičte se k ní 0×ffff00 |
Absolute address | @aa:16 | za instrukcí následuje šestnáctibitová konstanta (prvních 32kB a posledních 32kB ze 16MB) |
Absolute address | @aa:24 | za instrukcí následuje 24bitová konstanta |
Immediate | #xx:8 | za instrukcí následuje osmibitová konstanta |
Immediate | #xx:16 | za instrukcí následuje šestnáctibitová konstanta |
Immediate | #xx:32 | za instrukcí následuje 32bitová konstanta |
Program-counter relative | @(d:8,PC) | použito pro relativní skoky v rozsahu –126 do 128 |
Program-counter relative | @(d:16,PC) | použito pro relativní skoky v rozsahu –32766 do 32768 |
Memory indirect | @@aa:8 | použito u JMP a JSR, na adrese je uložen cíl skoku |
Zajímavý je režim @aa:16, který díky 16bitové konstantě umožňuje adresovat prvních 32kB paměti (nejvyšší bit konstanty je 0) a posledních 32kB (nejvyšší bit konstanty je 1). To souvisí s mapováním RAM a ((E)P)ROM do adresního rozsahu; toto adresování nepreferuje ani RAM ani ROM, ale umožňuje relativně krátkou instrukcí obsáhnout části obou pamětí.
7. Změny provedené v instrukční sadě
Instrukční sada i formát instrukčních slov zůstal z důvodů zpětné kompatibility sice zachován, ale i přesto můžeme v jádrech H8/300H najít některé změny. Původních 57 (55) instrukcí bylo rozšířeno na 64 (62) instrukcí, takže nárůst ve skutečnosti není tak velký (čísla v závorkách udávají počet instrukcí ve chvíli, kdy budeme PUSH a POP považovat za pouhé aliasy k instrukci MOV s post-inkrementem či pre-dekrementem adresy). Instrukce opět můžeme podle jejich funkce rozdělit do devíti kategorií. Tučně jsou zvýrazněny nové instrukce:
Skupina | Instrukce | Počet |
---|---|---|
Přenos dat | MOV, PUSH, POP, MOVTPE, MOVFPE | 5 (3) |
Aritmetické | ADD, SUB, ADDX, SUBX, INC, DEC, ADDS, SUBS, DAA, DAS, MULXU, MULXS, DIVXU, DIVXS, CMP, NEG, EXTS, EXTU | 18 |
Logické | AND, OR, XOR, NOT | 4 |
Posuny a rotace | SHAL, SHAR, SHLL, SHLR, ROTL, ROTR, ROTXL, ROTXR | 8 |
Bitové manipulace | BSET, BCLR, BNOT, BTST, BAND, BIAND, BOR, BIOR, BXOR, BIXOR, BLD, BILD, BST, BIST | 14 |
Nepodmíněné skoky | JMP, BSR, JSR, RTS | 4 |
Podmíněné skoky | Bcc (celkem 16 variant) | 1 |
Řízení procesoru | TRAPA, RTE, SLEEP, LDC, STC, ANDC, ORC, XORC, NOP | 9 |
Blokové přenosy | EEPMOV | 1 |
Celkem | 64 (62) |
Poznámka: instrukce MOVTPE a MOVFPE na zcela původních jádrech H8/300 taktéž nenalezneme.
8. Instrukce nově podporující 16bitové operandy
Minule jsme si popsali několik instrukcí, které dokázaly pracovat pouze s osmibitovými pracovními registry či osmibitovými konstantami. Většina instrukcí však byla rozšířena i pro zpracování šestnáctibitových operandů, což přispělo k ortogonalitě instrukční sady. Jedná se o následující instrukce:
# | Instrukce | Popis | Poznámka |
---|---|---|---|
1 | ADD | součet Rd = Rd + konstanta | i pro 16bitový registr |
2 | SUB | rozdíl Rd = Rd – konstanta | i pro 16bitový registr |
3 | INC | inkrementace Rd = Rd + 1 | i pro 16bitový registr |
4 | DEC | dekrementace Rd = Rd – 1 | i pro 16bitový registr |
5 | MULXU | součin Rd = Rd × Rs | 8bit×8bit či 16bit×16bit |
6 | DIVXU | podíl Rd = Rd ÷ Rs | dtto |
7 | NEG | výpočet Rd = -Rd | jen pro osmibitový cílový registr |
8 | CMP | Rd – konstanta s nastavením příznaků | i pro 16bitový registr |
9 | AND | Rd = Rd ∧ Rs | i pro 16bitové registry |
10 | AND | Rd = Rd ∧ konstanta | 16bitová konstanta |
11 | OR | Rd = Rd ∨ Rs | i pro 16bitové registry |
12 | OR | Rd = Rd ∨ konstanta | 16bitová konstanta |
13 | XOR | Rd = Rd ⊕ Rs | i pro 16bitové registry |
14 | XOR | Rd = Rd ⊕ konstanta | 16bitová konstanta |
15 | NOT | Rd = ¬ Rd | i pro 16bitový registr |
16 | SHAL | aritmetický posun registru Rd doleva | i pro 16bitový registr |
17 | SHAR | aritmetický posun registru Rd doprava | i pro 16bitový registr |
18 | SHLL | logický posun registru Rd doleva | i pro 16bitový registr |
19 | SHLR | logický posun registru Rd doprava | i pro 16bitový registr |
20 | ROTL | rotace registru Rd doleva | i pro 16bitový registr |
21 | ROTR | rotace registru Rd doprava | i pro 16bitový registr |
22 | ROTXL | rotace registru Rd doleva přes carry flag | i pro 16bitový registr |
23 | ROTXR | rotace registru Rd doprava přes carry flag | i pro 16bitový registr |
9. Instrukce nově podporující 32bitové operandy
Některé instrukce byly navíc rozšířeny takovým způsobem, aby mohly pracovat se dvěma 32bitovými registry popř. s jedním 32bitovým registrem a 32bitovou konstantou či hodnotou načtenou z operační paměti. Tyto instrukce jsou vypsány v následující tabulce (už bez podrobnějšího popisu):
# | Instrukce | Adresovací režimy |
---|---|---|
1 | MOV | #konstanta, Rn, @ERn, @(d:16,ERn), @(d:24,ERn), @ERn+, @-ERn, @aa:16, @aa:24 |
2 | ADD | #konstanta, Rn |
3 | SUB | #konstanta, Rn |
4 | CMP | #konstanta, Rn |
5 | INC | Rn |
6 | DEC | Rn |
7 | NEG | Rn |
8 | AND | #konstanta, Rn |
9 | OR | #konstanta, Rn |
10 | XOR | #konstanta, Rn |
11 | NOT | Rn |
12 | SHAL | Rn |
13 | SHAR | Rn |
14 | SHLL | Rn |
15 | SHLR | Rn |
16 | ROTL | Rn |
17 | ROTR | Rn |
18 | ROTXL | Rn |
19 | ROTXR | Rn |
Poznámka: z této tabulky mj. vyplývá, že většina pokročilejších adresovacích režimů je dostupná pouze pro instrukci MOV.
10. Nové aritmetické instrukce
Mezi nové aritmetické instrukce patří konverzní instrukce nazvané EXTU a EXTS. Tyto instrukce dokážou rozšířit původně osmibitovou hodnotu uloženou v pracovním registru na šestnáct bitů (pokud je operandem registr Rn) popř. rozšířit původně šestnáctibitovou hodnotu na 32 bitů (pokud je operandem registr ERn). Instrukce EXTU je jednodušší, protože provádí bezznaménkové rozšíření, tedy vlastně vynulování horních osmi resp. šestnácti bitů. Instrukce EXTS naproti tomu dokáže provést rozšíření znaménka, tj. kopii původního nejvyššího bitu čísla do horní poloviny slova či dvojslova.
Další dvě nové instrukce se jmenují MULXS a DIVXS. Jedná se o obdobu nám již známých instrukcí nazvaných MULXU a DIVXU, ovšem oba operandy jsou nyní chápány jako čísla se znaménkem (signed). Pozor je zapotřebí dát na to, že všechny čtyři instrukce MULXx a DIVXx dokážou pracovat buď s osmibitovými či šestnáctibitovými operandy, nikoli již s operandy 32bitovými.
11. Rozšíření sémantiky instrukce EEPMOV
I sémantika instrukce EEPMOV byla rozšířena. Původní funkce této instrukce se dala popsat následujícím pseudokódem:
while R4L > 0: @R6+ = @R5+ ; přenos z adresy uložené v R5 na adresu uloženou v R6 R4L--
Nově se při adresování používá plně 24bitová adresa (tedy registry ER5 a ER6) a počitadlo může být buď osmibitové (R4L) či šestnáctibitové (R4). Chování instrukce EEPMOV tedy můžeme popsat takto:
while R4L > 0: @ER6+ = @ER5+ ; přenos z adresy uložené v ER5 na adresu uloženou v ER6 R4L--
popř.:
while R4 > 0: @ER6+ = @ER5+ ; přenos z adresy uložené v ER5 na adresu uloženou v ER6 R4--
12. Další moduly, které lze nalézt na mikrořadiči
Většina mikrořadičů postavených na jádrech H8/300H obsahuje velmi podobně koncipované přídavné moduly, protože právě tyto moduly dělají mikrořadič tak užitečným, což se ostatně ukázalo již na úspěchu prvních osmibitových mikrořadičů (TMS1000 a Intel 8048). Některé z těchto modulů si popíšeme v navazujících kapitolách. Některé další moduly, například I2C či ovladač LCD, dnes nebudou podrobněji popsány.
13. Sériové porty
Modul pro sériovou komunikaci podporuje jak asynchronní přenos (tj. UART – Universal Asynchronous Receiver/Transmitter), tak i režim synchronní, tj. řízený hodinovým signálem. V asynchronním režimu lze samozřejmě volit přenosovou rychlost a to v poměrně širokém rozmezí (rychlost je odvozena od frekvence krystalu děličkou). Dále pak lze nakonfigurovat počet datových bitů (5, 7 nebo 8), počet stop bitů (1 nebo 2) a paritní bit (sudá parita, lichá parita či žádný paritní bit). Při konfiguraci sériového synchronního přenosu se volí pouze přenosová rychlost, protože data jsou v tomto případě vždy přenášena po celých bajtech. Některé čipy obsahují podporu pro dva nezávisle na sobě pracující asynchronní sériové porty, takže na čipu nalezneme dvojici pinů RXD a TXD, které jsou doplněny dvojicí pinů SCK (hodiny pro synchronní režim přenosu).
14. PWM a ADC
Čipy postavené na jádrech H8/300H typicky obsahují čtrnáctibitový PWM (pulse width modulator) se dvěma na sobě nezávislými výstupními kanály. Generovaný signál je opět odvozen od frekvence hodinového signálu, který je vydělen konstantou 2, 4, 8 či 16. Po připojení dolní propusti je možné PWM použít i ve funkci jednoduchého D/A převodníku (ovšem záleží na konkrétní aplikaci i na kvalitě dolní propusti).
Analogově-digitální převodník má osm přepínatelných vstupů, rozlišení 10 bitů a poměrně rychlé sledování analogové veličiny (cca 12 mikrosekund na každý kanál). V praxi však bývá rozlišení nižší, počítat lze s 8 až 9 bity (to ale platí i pro mnoho dalších ADC implementovaných přímo na jednom čipu s mikrořadičem).
15. Čítače a časovače
Jednotlivé čipy s jádrem H8/300H se od sebe v několika ohledech liší; týká se to i konfigurace čítačů a časovačů. Na většině mikrořadičů však najdeme alespoň dvojici plně šestnáctibitových čítačů/časovačů, jejichž možnosti konfigurace jsou poměrně široké. Mohou například začít automaticky generovat jiný výstupní signál po dosažení určitého času (včetně PWM), na základě zadaných podmínek se může generovat přerušení, přečíst aktuální hodnoty na vstupních pinech atd. U dalších (dražších) čipů z téže rodiny nalezneme i větší množství čítačů (3–4).
Poznámka: samostatný časovač „F“ je sice šestnáctibitový, ale lze ho nakonfigurovat i takovým způsobem, že bude pracovat jako dva na sobě nezávislé osmibitové časovače („FH“ a „FL“), přičemž každý z nich může nastavovat výstupní piny atd.
16. Odkazy na Internetu
- H8/300H Series Software Manual
https://www.renesas.com/en-us/doc/products/mpumcu/001/rej09b0213_h8300h.pdf - Renesas H8/300H Series Manuals
https://www.manualslib.com/products/Renesas-H8–300h-Series-2312446.html - H8 Family
https://en.wikipedia.org/wiki/H8_Family - H8/300 and H8/300L
http://nah6.com/~itsme/download/ibutton/h8_8bit.pdf - H8 Family
https://www.renesas.com/en-us/products/microcontrollers-microprocessors/h8.html - (GCC) Status of Supported Architectures from Maintainers' Point of View
https://gcc.gnu.org/backends.html - (GCC) H8/300 Options
https://gcc.gnu.org/onlinedocs/gcc/H8_002f300-Options.html#H8_002f300-Options - GCC for SuperH,H8/300,AVR
http://mes.osdn.jp/h8/gcc.html - H8/3802, 38002S, 38004, 38104 (manuály k čipům)
https://www.renesas.com/en-us/document/hw-manual?hwLayerShowFlg=true&prdLayerId=184&layerName=H8%252F3802%252C%2B38002S%252C%2B38004%252C%2B38104&coronrService=document-prd-search&hwDocUrl=%2Fen-us%2Fdoc%2Fproducts%2Fmpumcu%2F001%2Frej09b0024_h83802.pdf&hashKey=c5e1fa0a18c01e6c789bc7b5c0184ed9 - Addressing mode (Wikipedia)
https://en.wikipedia.org/wiki/Addressing_mode - Renesas SH Instruction Set Summary
http://shared-ptr.com/sh_insns.html - SH-4 RISC Processor by HITACHI
http://www.cs.umd.edu/~meesh/cmsc411/website/projects/risc/risc.htm - SH-4 RISC Processor
http://www.cs.umd.edu/~meesh/cmsc411/website/projects/risc/sh-4.htm - SuperH RISC engine Family Features
https://www.renesas.com/en-us/products/microcontrollers-microprocessors/superh/superh-features.html - Orthogonal instruction set
https://en.wikipedia.org/wiki/Orthogonal_instruction_set - Status Register
https://en.wikipedia.org/wiki/Status_register - 6800 Instruction Set
http://www.electronics.dit.ie/staff/tscarff/6800/Instructions/instructions.htm - Assembly language today
http://beust.com/weblog/2004/06/23/assembly-language-today/ - Calling subroutines
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0100a/armasm_cihcfigg.htm - Art of Assembly – Arithmetic Instructions
http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter6/CH06–2.html - X86 Assembly/Arithmetic
https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic - ARM subroutines & program stack
http://www.toves.org/books/armsub/ - Programming from the Ground Up Book – Summary
http://savannah.nongnu.org/projects/pgubook/ - The 6502 overflow flag explained mathematically
http://www.righto.com/2012/12/the-6502-overflow-flag-explained.html