pokud to budeš takhle hodnotit, můžeš říct, že binární kód je primitivní, vždyť to je jen kombinace jedniček a nul.
ASM nemá moc abstrakcí a je komplikovaný na vytváření, úpravu/opravu nebo čtení. Když děláš něco v ASM, máš vedle sešit a tam si všechny podklady, adresy, struktury, závislosti sepisuješ, jinak se v tom ztratíš. Vyšší jazyky jsou často samodokumentační.
jak by byl svět jednoduchý ;-)
http://www.funpic.hu/_files/pictures/original/90/40/4090.jpg
Tak se podívejte na něco, kde se skutečné kódovalo binárně:
https://www.fi.muni.cz/usr/jkucera/pv109/vystavka/xprocha1_04-01.html
Když i feritové paměti zapomněly, třeba po ošklivém výpadku napájení, tak se musel pěkně binárně nacvakat zavaděč zavaděče (IBL, initial binary loader):
vypnout ochranu paměti
binárně adresu do program counteru, enter
instrukci, enter (tlačítko STORE, zároveň inkrementovalo PC), těch instrukcí bylo asi 5
zapnout ochranu paměti
nastavit PC, založit děrnou pásku s diskovým zavaděčem a spustit
zastavit, nastavit PC a spustit
No a všechny údaje se zadávaly 16 tlačítky na čelním panelu, jedno slovo bit po bitu.
Sestava na tom obrázku je opravdu hodně stará, s psacím strojem jsem to sice zažil, ale už tam byl i CRT terminál. Psací stroj Consul měl totiž vadu, dal se uštvat, tak že hrozilo zaseknutí kláves - další oříšek pro programátora, když chtěl něco vypsat co nejrychleji, ale programově se to nedalo zjistit.
No tuhle jsem zrovna na půdě narazil na manuál k ASM pro 8051. 1250 stránek... Tak ti nevím.
V reálu se těch "pět instrukcí" rozšíří ještě o další, přibudou podmínky, flagy,... U CISCu se mění i délka instrukcí jak v Bytech, tak v taktech. Někde je jako bonus booleovský procesor, jinde násobička nebo FPU, další podpoduje třeba SIMD.U dalšího jsou tři sady instrukcí, pro 8b, 16b a 32b. Některý registry jsou vyhrazený (např. stack pointer, return register), některý registry mají specifickou instrukci pro čtení a zápis, takže mov/ld tam nefunguje. Někde je zamykání, takže se musí provést přesná sekvence instrukcí. Interrupt je kapitola sama pro sebe... A někde je tak skvělá pipeline, že si musíš hlídat pořadí instrukcí. A třeba u MIPSu musíš při volání funkce napřed alokovat stack frame a pak do něj teprve zálohovat registry...
A to všechno se brouk od brouka liší.
Složitost není v těch instrukcích. A je jich víc, aritmetické, logické, bitové, přesuny, skoky, návraty, řízení přerušení atd. Ta složitost vychází z operandů. CISC mají šílený bordel v tom, co se s čím dá použít. RISC tam sice nemají bordel, ale zase to dohání tím, že umí někdy i desítky typů operandů.
Řečeno na příkladu instrukce "LD N,M" v Z80. Je jen jedna. Ale jaképak umí způsoby zadání operandů?
Pro N (kam):
1. [např. A] Název registru, do kterého se vloží hodnota
2. [např. (BC)] Název registru, že kterého se vezme adresa, na kterou se vloží hodnota
3. [např. (NN)] Konstanta, která je odkazem na adresu, kam se vloží hodnota
4. [např. (IX+N)] Konstanta a název registru - z registru se načte hodnota, přičte se konstanta a výsledkem je adresa, kam se vloží hodnota
Pro M (co):
1. [např. (A)] Název registru, ze kterého se bere hodnota
2. [např. (BC)] Název registru, že kterého se vezme adresa, ze které se bere hodnota
3. [např. (NN)] Konstanta, která je odkazem na adresu, ze které se bere hodnota
4. [např. (IX+N)] Konstanta a název registru - z registru se načte hodnota, přičte se konstanta a výsledkem je adresa, odkud se bere hodnota
5. [např. N] Konstanta, která je sama hodnotou
A teď se ještě můžeme dohadovat, zda PUSH a POP jsou samostatná kategorie, nebo je to jen jiný název pro LD pracující s registrem SP. A co třebas takové EX a EXX? Říkal někdo LDI a LDE? Počítá se sem i LDIR a LDDR, nebo to už jsou instrukce skoku? Co třebas IN, OUT, OUTI a podobné legrace? Vlastně je to podobné LD, jen procesor navíc nastaví na jednom vývodu příznak, že nechce RAM, ale PORT.
Teď si to drobně zkomplikujme tím, že LD může být 8 bit nebo 16 bitů a podle typu parametrů se pak liší i délka instrukce (kolik zabírá bytů). A nakonec ještě fakt, že je to CISC - takže nejsou dostupné zdaleka všechny kombinace. Z celkových 675 kombinací je to jen 181.
Ono to sice vypadá hezky, že je to prostě jedna instrukce. Ale naučit se jí byla práce na pár dnů a nové věci se člověk dozvídal i po roce. A to je to prosím Z80, velmi starý osmibit. U 16bitů je těch možných operandů ještě víc - součty dvou explicitně zadaných registrů, součet konstanty nebo registru a dalšího implicitního registru (zdravíme relativní adresování v rámci segmentu) atd.
@Karel
To co popisujete není IMO CISC vs RISC, ale ortogonalita: https://cs.wikipedia.org/wiki/Ortogon%C3%A1ln%C3%AD_instruk%C4%8Dn%C3%AD_sada
On je ještě rozdíl mezi "naivním assemblerem" (a = d[i]; i++) a "efektivním assemblerem" (a = d[i++]). Ten efektivní se ohromně špatně portuje na jiné procesory, protože efektivity dosahuje použitím instrukcí, které dělají více věcí najednou.
Takže místo čtyř instrukcí pro zkopírování bytu z adresy v jednom registru na adresu v jiném registru, zvýšení hodnoty prvního registru, zvýšení hodnoty druhého registru a snížení hodnoty třetího registru se použije jedna, která provede všechno (viz Z80 a LDI). No a co s tím pak ve chvíli, kdy to portujete na procesor, kde LDI není? Obvykle to jde rozepsat na jednotlivé pod-instrukce, ale občas se vám stane, že se výsledek chová jinak k příznakům. Kupříkladu že vám instrukce X na první architektuře nastavuje příznak O podle výsledku a na příznak Z nesahá, zatímco na druhé architektuře to vždy nastaví O i Z. A jako na potvoru autor původního programu tohohle využil.