Prenderò la tua domanda alla lettera e discuterò principalmente di microprocessori, non di computer in generale.
Tutti i computer hanno una sorta di codice macchina. Un'istruzione è composta da un codice operativo e uno o più operandi. Ad esempio, l'istruzione ADD per Intel 4004 (il primo microprocessore) è stata codificata come 1000RRRR, dove 1000 è il codice operativo per ADD e RRRR rappresentava un numero di registro.
I primissimi programmi per computer sono stati scritti a mano, codificando a mano l'1 e lo 0 per creare un programma in linguaggio macchina. Questo è quindi programmato nel chip. I primi microprocessori utilizzavano la ROM (memoria di sola lettura); questo è stato successivamente sostituito da EPROM (ROM programmabile cancellabile, che è stata cancellata con luce UV); ora i programmi sono generalmente programmati in EEPROM ( "Elettricamente ...- EPROM" , che può essere cancellato su chip), o in particolare nella memoria Flash.
La maggior parte dei microprocessori ora può eseguire programmi dalla RAM (questo è praticamente uno standard per tutto tranne i microcontrollori), ma in primo luogo deve esserci un modo per caricare il programma nella RAM. Come ha sottolineato Joby Taffey nella sua risposta, questo è stato fatto con interruttori a levetta per Altair 8080, che era alimentato da un Intel 8080 (che ha seguito i 4004 e 8008). Nel tuo PC, c'è un po 'di ROM chiamata BIOS che viene utilizzata per avviare il computer e caricare il sistema operativo nella RAM.
Il linguaggio macchina diventa noioso molto velocemente, quindi sono stati sviluppati programmi assembler che prendono un linguaggio assemblatore mnemonico e lo traducono, di solito una riga di codice assembly per istruzione, in codice macchina. Quindi invece di 10000001, si scriverebbe ADD R1.
Ma il primo assemblatore doveva essere scritto in codice macchina. Quindi potrebbe essere riscritto nel proprio codice assembler e la versione in linguaggio macchina lo utilizzava per la prima volta. Successivamente, il programma potrebbe assemblare se stesso. Questo si chiama bootstrap e viene eseguito anche con i compilatori: in genere sono prima scritti in assembler (o in un altro linguaggio di alto livello), quindi riscritti nella loro lingua e compilati con il compilatore originale fino a quando il compilatore non può compilare se stesso.
Dal momento che il primo microprocessore è stato sviluppato molto tempo dopo la presenza di mainframe e minicomputer e il 4004 non era comunque adatto all'esecuzione di un assemblatore, Intel probabilmente ha scritto un cross-assemblatore che funzionava su uno dei suoi grandi computer e ha tradotto il codice assembly per il 4004 in un'immagine binaria che potrebbe essere programmata nella ROM. Ancora una volta, questa è una tecnica comune utilizzata per il porting dei compilatori su una nuova piattaforma (chiamata cross-compilation ).