Zacznijmy po kolei:
- komp rozumie tylko ciąg zer i jedynek - człowiek dla łatwiejszej orientacji podzielił ciągi na bajty czy słowa. I programował tak, jak komputer umiał - składając z zer i jedynek instrukcje dla komputera. Załóżmy, że komputer miał 8 rejestrów, oznaczonych literami od A do H - i do wstawienia do rejestru A wartości 1 potrzebny był kod "0x35 0x01", ale już przy rejestrze B kod mógł brzmieć "0x71 0x01". Tak samo z dodawaniem liczby do rejestru, odejmowaniem... Programowanie szybko zaczęło męczyć. Ponieważ jednak (Crozin dobrze gada, polać mu) każdy producent procesora podawał (w specyfikacji procesora) takie rzeczy jak mnemonik (czyli : ADD, SUB, MOV, JMP, ...), i wartość, jaka temu mnemonikowi odpowiada (+opcjonalnie parametry), stosunkowo łatwo było napisać sobie...
- ASEMBLER - czyli tłumacz mnemoników bezpośrednio na binarny kod maszynowy. Dodatkową zaletą pisania w asemblerze stało się to, że już nie trzeba było przeliczać adresów do skoków (JMP), asembler sam potrafił o to zadbać, trzeba było tylko w odpowiednim miejscu kodu umieścić tzw. etykietę, którą podawało się w instrukcjach JMP czy CALL jako adres do skoku. Dodatkowo oczywiście pojawiły się automatyczne konwersje ciągu znaków (podanych w cudzysłowach) na ich kody ASCII i umieszczenie w poszczególnych komórkach pamięci, można było używać stałych... Życie stało się prostsze.
- Ale ludzie chcieli więcej i łatwiej, i dlatego już w latach '50-'60 powstały takie języki jak Fortran (do dziś wielu naukowców go używa, z uwagi na nieprawdopodobnie dobrej jakości biblioteki numeryczne), Algol (prekursor Pascala) czy Cobol (język dla biznesu). Nieco później (na początku lat '70) powstały dopiero C czy Prolog.
Z ciekawostek: C, C++, Unix, tranzystor - to wszystko łączą dwa słowa: "Bell Labs".
P.S.
Zobacz sobie
http://www.thegeekstuff.com/2011/10/c-prog...-an-executable/ - tu masz fajnie pokazane, jak linuksowy gcc kompiluje program "Hello World", a także (co może Cię bardziej zainteresować), jak wygląda kod asemblera takiego programu.