Tomaré tu pregunta literalmente y hablaré sobre todo de microprocesadores, no de computadoras en general.
Todas las computadoras tienen algún tipo de código de máquina. Una instrucción consta de un código de operación y uno o más operandos. Por ejemplo, la instrucción ADD para el Intel 4004 (el primer microprocesador) se codificó como 1000RRRR donde 1000 es el código de operación para ADD y RRRR representaba un número de registro.
Los primeros programas de computadora se escribieron a mano, codificando a mano los 1 y 0 para crear un programa en lenguaje de máquina. Esto luego se programa en el chip. Los primeros microprocesadores utilizaron ROM (memoria de solo lectura); luego fue reemplazado por EPROM (ROM programable borrable, que se borró con luz UV); ahora los programas generalmente se programan en EEPROM ( "Electrically ...- EPROM" , que se puede borrar en el chip), o específicamente en la memoria Flash.
La mayoría de los microprocesadores ahora pueden ejecutar programas sin RAM (esto es más o menos estándar para todo menos los microcontroladores), pero en primer lugar tiene que haber una forma de cargar el programa en la RAM. Como Joby Taffey señaló en su respuesta, esto se hizo con interruptores para el Altair 8080, que funcionaba con un Intel 8080 (que seguía al 4004 y al 8008). En su PC, hay un poco de ROM llamada BIOS que se utiliza para iniciar la computadora y cargar el sistema operativo en la RAM.
El lenguaje de máquina se vuelve tedioso muy rápido, por lo que se desarrollaron programas de ensamblador que toman un lenguaje de ensamblador mnemónico y lo traducen, generalmente una línea de código de ensamblaje por instrucción, en código de máquina. Entonces, en lugar de 10000001, uno escribiría ADD R1.
Pero el primer ensamblador tuvo que escribirse en código máquina. Entonces podría reescribirse en su propio código de ensamblador, y la versión en lenguaje de máquina solía ensamblarlo la primera vez. Después de eso, el programa podría ensamblarse. Esto se llama bootstrapping y también se realiza con compiladores: generalmente se escriben primero en ensamblador (u otro lenguaje de alto nivel), y luego se reescriben en su propio idioma y se compilan con el compilador original hasta que el compilador pueda compilarse.
Dado que el primer microprocesador se desarrolló mucho después de que existieran los mainframes y las minicomputadoras, y el 4004 no era realmente adecuado para ejecutar un ensamblador de todos modos, Intel probablemente escribió un ensamblador cruzado que se ejecutó en una de sus computadoras grandes, y tradujo el código de ensamblaje para el 4004 en una imagen binaria que podría programarse en la ROM. Una vez más, esta es una técnica común utilizada para portar compiladores a una nueva plataforma (llamada compilación cruzada ).