32bit mi naopak prijde jako velice vhodny assembler pro rucni programovani (alespon pro ARM7, kde clovek nemusi resit interlocky aby kod zbytecne necekal, ale da se i na ARM9). Po chvili cviku si clovek na tu symetrii celkem zvykne. Navic je ARM oproti jinym RISC celkem standardni (ma Carry flag, nema zpozdeny skok). Velkou vyhodou je take jednoducha instrukcni sada -- da se to naucit za den.
Naopak Thumb nemam zrovna moc rad, prijde mi ze pri rucnim programovani a dobrem vyuziti barrel shifteru ta vyhoda ve vyssi hustote kodu neni zase tak podstatna (protoze proti ni pusoubi taky dvouadresovost, taky nemuzu pouzivat vsechny registry libovolne ale nizsih 8 a vyssich 8 je oddeleno, coz zpusobuje ze nakonec tech instrukci potrebuju vic takze to bezi pomaleji a neni to ani o mnoho mensi).
Podle mych zkusenosti je dobre mit alespon povedomi o to, na cem vlastne ten ceckovy program (po prelozeni) pobezi a jake jsou tedy zakladni vlastnosti te ktere architektury.
Napriklad diky existenci bitu Carry (nektere procesory ho nemaji) lze rici, ze asi bude docela jednoducha implementace viceslovni aritmetiky (i kdyz docela pochybuji, ze to nekdo dokaze optimalne napsat v cecku :-), jak se bude cecko chovat ke statickym promennym, jak a zda vubec se bude provadet zarovnavani operandu, jestli je vubec mozne efektivne provadet aritmeticky posun doprava (na 6502 se to muselo hackovat) atd. atd.
On ARM je z tohoto pohledu vlastne docela "mainstreamovy" procesor, ale na nejakem DSP se clovek muze divit, ze treba char vlastne nema osm bitu, ze float/double nejsou podle IEEE 754 atd.
Asi jsem něco přehlédl, ale jak se bude řešit situace, kdy zavolaný podprogram bude volat další podprogram? Dojde tak přece k přepisu v registru schované původní návratové adresy....?
To ji musím ručně schovávat někam do RAM?
Starému opelíchanému assembleristovi připadá takový procesor dost primitivní. Naposled jsem podobně bez stacku řešil návraty z podprogramů na ADT4000 :-)
Něco o MMU ARMu bude?
Kdyz mate podprogram ktery bude jeste neco volat, tak proste lr registr ulozite na stack (spolu s ostatnimi registry ktere nechcete prepsat) na zacatku toho podprogramu. Na to jsou specialni instrukce LDM/STM, ktere nekem do pameti (indexovane zadanym registrem, zde stack pointerem pro ktery se tradicne vyuziva r13) ulozi seznam registru (podle bitove masky) a pouzijete variantu ktera navic ten stack pointer inkrementuje. Kod pak vypada takto
stmfd sp!, {r3,r4,r5,lr}
.... telo funkce ... zde muzu volat podprogram
ldmfd sp!, {r3,r4,r5,pc}
Vsimete si ze ldm obnovi stejne registry, s vyjimkou lr. Navratovou adresu vlozi primo do pc, cimz se provede navrat z podprogramu.
Taky se to dobre hodi pro tail recurstion elimination. Pokud volat nejakou funkci tesne pred navratem z podprogramu, prelozi to gcc takto:
stmfd sp!, {r3,r4,r5,lr}
... vnitrek funkce ...
ldmfd sp!, {r3,r4,r5,lr}
b poslednifunkce
cimz se zamezi zbytecnemu plytvani mista na zasobniku (pokud jste zvykli z lispu psat cykly pomoci rekurze tak nedojde ke zbytecnemu pouzivani zasobniku).
On ten procesor skutecne je primitivni, je to by design, neni to chyba :-) [neco jako MIPSy v prvnich verzich]
Jinak ten call se resi ruzne, podle povahy problemu. Bud se pres Rx (vetsinou R13) implementuje zasobnik v RAM, podobne jako na jinych procesorech, nebo se u nekterych subrutin preorganizuji registry tak, ze je navratova adresa ulozena do neceho jineho nez LR. Dtto s predavanim parametru - vetsinou pres registry, ktere se v subrutine pres LDM/STM mohou odlozit, ale dobry prekladac se tomu zuby nehty bude vyhybat.
O MMU ARM, SIMD atd. se jeste urcite zminim.
Ten skok s tím odčítáním osmičky mě fakt zaujal. Taková drobnost zpravidla ukazuje na naprosto nekoncepční vývoj produktu. A přitom je na první pohled jasné, že se mýchají interní věci procesoru s externě dodaným kódem, který nemá povinnost tyto interní záležitosti znát. Každému analytikovi, který by takový návrh uviděl, by se v hlavě rozsvítil zářivý vykřičník a měl by sakra velký problém takový systém pustit dál.
Zadna nekoncepcnost. Naopak to meli promyslene aby usetrili incrementor a neztratili pritom 1 takt pri provadeni skoku. Vzhledem k tomu ze offsety pocita assembler je od toho programator celkem odstinen (navic je to zdokumentovane, takze v tom nevidim problem).
Je pravda ze u novych verzi to uz nema puvodni vyznam, ale uprime receno, kdyby dnes nekdo uplne od zacatku navrhoval procesor pro co nejlepsi vykon a nejnizsi spotrebu, tak by stejne zvolil jine instrukce.
... naprosto nekoncepční ... zářivý výkřiční ...
Sorry, ale to je hlod par excellence. Kódování (a odečítání osmičky) snad řeší assembler a ten to ví. Nebo snad píšeš přímo v hexa kódu? A i kdyby, tak jakej je závažnej rozdíl mezi tím od kterýho bodu se počítá výsledná adresa?
Vnitřní strukturu procesoru do značný míry musí znát každej překladač. Každej procesor má svoje speciality.
No ja jsem se nad tim zkousel zamyslet, jak je to vlastne u jinych procesoru, ktere to 'nejak' resi.
Bud se puvodni hodnota PC musi kopirovat pri propagaci instrukce pres pipeline (takze 2 dalsi registry, coz je tak minimalne 512 tranzistoru pri 32bitove sirce, 6 tranzistorech na bunku a pripojeni na sbernici) nebo by se adresa musela jeste jednou propasirovat pres ALU, takze bud dalsi ALU ci alespon
'inkrementator' (xxx tranzistoru) nebo zpozdeni skoku o dalsi takt.
Nakonec je asi ten problem +-8 vyresen docela dobre :-)
A to je na tom ARM jeste dobre! Napriklad puvodni verze nemela branch delay sloty, ktery by lidem mohly plest hlavu, nebyl to ani superskalarni procesor (takovy Pentia I byly dost komplikovany pri parovani instrukci), proste pohodicka a assembler at si tech +-8 vyresi sam; naposledy jsem relativni skoky rucne pocital u PMI-80, ale to bylo z jinych duvodu - programovalo se to primo v hexa kodu :-)
Jojo, zlaty casy, kdy se Z80 programovala primo v hexu :-). Jeste dodnes, kdyby me nekdo vzbudil ve 4 hodiny rano, bych mu mohl odvykladat "F-E-D-C-B-A-9-8-7-6-5-4-3-2-1", jak jsem pred 25ti lety pocital offsety skoku dozadu :-).
Mimochodem, i Z80 pocital skoky od NASLEDUJICI instrukce, takze 18 00 skocil na nasledujici instrukci, takze vlastne nic nedelal. V assembleru se naopak znakem $ mysli adresa samotne instrukce, takze kdyz nekdo napsal JR $+2, prelozilo se to jako 18 00 a nikdo se tomu nedivil.
Tyhle drobnosti naopak řeší poměrně rozsáhlé technologické problémy. Výkonnostní penalizace tam není žádná, zatímco úspora komplexity a počtu tranzistorů je zřejmá. S ohledem na to, kolik měl ARM tranzistorů a kolik jich bylo touto "osmičkou" ušetřeno se bavíme už v řádu promile, což je docela slušná úspora. Chápu že dnes, kdy už ani není na ten křemík co přidat a polovina plochy je prázdná, to lidé vnímají jinak.
To tvoje "mychani" mi pripada jako mnohem zarivejsi vykricnik. :D Takovej "analytik" by byl fakt hodne uzitecnej, kdyz by ho zajimaly takovy pic...y, jako format ulozeni relativni adresy v kodu instrukce, uprednostnovany pred usporou mista na chipu a zefektivneni cinnosti obvodu.
Tady je zajimave video, ktere s ARM souvisi: http://www.youtube.com/watch?v=VK5AZrg3ZD8
Cloveku je smutno, kdyz vzpomina na tu dobu, kdy se tady v Evrope jeste neco opravdu delalo a nebyli tolik premnozeni humanitni zvanilove...Mit tak moznost prenest se v case zpatky....