Maar het aller aller grootste nadeel van binair (of machinecode zoals het echt heet) programmeren is dat je na het toevoegen van 1 instructie al je jump (en waarschijnlijk ook nog andere) instructies moet gaan nalopen en veranderen.
Voorbeeld (even prut opcodes):
0x0: 0x90
0x1: 0x0A 0x01 0x39
0x4: 0xF9 0x01 0x00 //Stel dit is een jump naar locatie 0x1
Als je dan een instructie invoegt op locatie 1: van 2 bytes, dan moet je de jump op 0x04 (dan op 0x06) zo aanpassen dat hij naar locatie 0x03 jumpt. Dit is natuurlijk op te lossen door relatieve jumps te gebruiken, maar dan heb je het probleem als je een instructie vlak voor de jump wilt invoegen.
Kortom, voor een kleine wijziging moet je veel code veranderen.

Als je trouwens direct machinecode programmeert (dus in een hex-editor een .com-file maakt, kan je ook geen commentaar bij je code zetten, wat in dit geval best wel makkelijk zou zijn)
Om dit zo veel mogelijk te voorkomen moet je je programma dus van te voren helemaal uitdenken, dan in een soort assembly opschrijven en dan pas omzetten in binair, intikken en hopen dat het klopt.
De eerste programma's moeten natuurlijk in machinecode zijn geschreven, omdat er simpel weg niets anders was om in te programmeren. Maar zodra je de eerste assembler hebt, kun je de volgende assembler in assembly programmeren.

Je kunt dan ook bijv. een C compiler in assembly programmeren, maar zodra je die hebt kun je een nieuwe C compiler in de oude C compiler programmeren. En dan kun je natuurlijk weer een nieuwe assembler schrijven in C code met behulp van de C compiler.

(Dit heet bootstrapping)