Altair BASIC, the first product created by Micro-Soft, was programmed using Assembly. Some of this was assembled by a program running on a PDP-10 but some was assembled by hand.
He took out his notebook and quickly scribbled down a loader program in assembly language, then manually translated that into the ones and zeros the Altair would understand.
– START-UP Albuquerque and the Personal Computer Revolution
Assembly language is an easy-to-read version of machine code. An assembly compiler converts acronyms, such as
MOV, into a series of bytes, interpreted as machine code instructions by the CPU. Depending on the parameters, addressing modes etc. an acronym might have multiple different byte values.
MOV in the Intel 8080 (the processor in the Altair 8800) is a notable example - every combination of moving values from one register to another has a separate machine code instruction taking up almost half of the instruction set. There are often added features, such as the ability to reference a section of code or a memory value by a name (known as a label) instead of by the position in the program, but a rudimentary assembler could conceivably be made using a find-and-replace tool. This simplicity is how Paul Allen was able to convert his loader program from assembly to machine code using only a notebook and pen.
This loader program was originally used to allow the BASIC interpreter to be loaded from a roll of paper tape. The program could be put into a Teletype machine and "typed" into the Altair 8800, where the loader program would store it into memory. From there it could be run on the Altair 8800 by setting the instruction pointer to the start of the interpreter. The loader program itself was entered by typing it by hand into the computer, where another loader program would take the loader program and load that into memory. The loader loader was hard-wired into the computer. This is a problem known as bootstrapping, from the saying "to pull oneself up by one's bootstraps".
The principle of this bootstrapping remained roughly the same in the final version of Altair BASIC. A program running on the computer would know how to interface with the tape reader - after the user's copy of BASIC was put into the paper or cassette tape reader it would be read into the computer's memory and executed. From there programs could either be read into the memory reserved for the BASIC program from another tape or typed in manually. There was also a feature allowing the user to save their programs.
Altair BASIC is an interpreter, not a compiler. This means that the BASIC program is not converted to machine code. Instead it is treated as data that BASIC reads to determine what section of its code to run when. For example, if you have the BASIC program:
A = 1
B = 2
C = A + B
it will not be compiled to machine code. Instead, the interpreter will set the variable
1, then set the variable
2, then read
B, then add them, then set
C to the result. This makes BASIC much slower than native machine code, but it is has the advantage of being easier to program and debug.
The CPU only understands machine code, but the interpreter "understands" whatever programming language it is designed to interpret. For example, if the command
PRINT is being interpreted, the interpreter's instruction pointer will jump to the code that prints things to the screen.
You could view the combination between the interpreter and it's data as a machine code program that executes the interpreted program, but it's not really "compiled" as there is no compilation step in between "representation of the source code" and "execution of said code". If the program that ran BASIC instead replaced
PRINT with a jump to the code that prints things to the screen etc. then it could be said to be a compiler that produces a program that requires BASIC as a "runtime library" and the code would run a little bit faster as it's already done all of the lookups and code replacement. However, I do not know of any BASIC compilers.
The interpreter is programmed for one specific processor; this means that it will have to be partially modified to work on a different but similar processor and almost completely reprogrammed to work on a very different processor. The interpreter is also programmed for a specific type of computer but, as the Intel 8080 became very popular after the Altair 8800, Microsoft BASIC only required small modifications to run on other 8080-based computers. Microsoft made a lot of money from this. See the questions with a BASIC tag for more details as to variants of BASIC.
ROM was used in many computers to store BASIC interpreters. This meant that BASIC was already effectively "in memory" and did not need to be loaded in by the user - a very time-consuming process. See Why was BASIC built into so many operating systems? for reasons why BASIC would be included like this.