Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I always wonder this, and perhaps I need a good history lesson on programming languages. But since most compilers nowadays are made in C, how were the very first compilers made (AKA before C) or were all the languages just interpreted?

With that being said, I still don't understand how even the first assembly language was done, I understand what assembly language is but I don't see how they got the VERY first assembly language working (like, how did they make the first commands (like mov R21) or w/e set to the binary equivalent?

share|improve this question
6  
There was a comically inept programmer on my team once, where all he did was complain about C#. We used to joke about a fictional language he invented called Crunk. A little known fact about Crunk, it is the first language where the compiler was ALSO written in Crunk. :) –  maple_shaft Jun 30 '11 at 12:19
1  
Why would someone complain about C#? has he never used smalltalk or Lisp? lol –  Mercfh Jun 30 '11 at 13:38
2  
possible duplicate of C compiler and Dennis Ritchie –  vartec Jun 30 '11 at 14:02
4  
@maple_shaft: to be fair, the gcc compiler is written in C. That actually isn't a problem if you have a good cross compiler to compile the first version. The first C compiler, of course, had to be written in another language. –  Scott Whitlock Jun 30 '11 at 15:03
4  
possible duplicate of How was the first compiler written? –  Greg Hewgill Jun 30 '11 at 19:35

7 Answers 7

up vote 75 down vote accepted

Ha, I've done this. Many CPUs have simple, fixed-size instructions that are just a couple of bytes long. For a simple CPU like a Motorola 6800 for example, you could fit all of its instructions on a single sheet of paper. Each instruction would have a two-byte opcode associated with it, and arguments. You could hand-assemble a program by looking up each instruction's opcode. You'd then write your program on paper, annotating each instruction with its corresponding opcode. Once you had written out your program, you could could burn each opcode in sequence to an EPROM which would then store your program. Wire the EPROM up to the CPU with just the right instructions at the right addresses, and you have a simple working program. And to answer your next question, yes. It was painful (we did this in high school). But I have to say that wiring up every chip in an 8-bit computer and writing a program manually gave me a depth of understanding of computer architecture which I could probably not have achieved any other way.

More advanced chips (like x86) are far more difficult to hand-code, because they often have variable-length instructions. VLIW/EPIC processors like the Itanium are close to impossible to hand-code efficiently because they deal in packets of instructions which are optimized and assembled by advanced compilers. For new architectures, programs are almost always written and assembled on another computer first, then loaded into the new architecture. In fact, for firms like Intel who actually build CPUs, they can run actual programs on architectures which don't exist yet by running them on simulators. But I digress...

As for compilers, at their very simplest, they can be little more than "cut and paste" programs. You could write a very simple, non-optimizing, "high level language" that just clusters together simple assembly language instructions without a whole lot of effort.

If you want a history of compilers and programming languages, I suggest you GOTO a history of FORTRAN.

share|improve this answer
25  
+1: "... I suggest you GOTO a history ..." groan :) –  Binary Worrier Jun 30 '11 at 12:31
22  
. . . and shoudn't that be "... I suggest you JMP to a history ..." –  Binary Worrier Jun 30 '11 at 12:33
7  
@Dave: You realise you've doomed yourself to death by Velociraptor? –  Binary Worrier Jun 30 '11 at 12:38
5  
They "knew" because they were literally hard-wired to perform that operation when they saw a 101010100 signal for a given instruction. They actually have an on-chip unit responsible for instruction decoding instructions: en.wikipedia.org/wiki/Decoder –  Dave Markle Jun 30 '11 at 12:54
3  
Worth adding: the compiler for a new language, when written in that same new language, is sometimes compiled with a "proto-compiler" written in another language that produces demonstrably-correct, but horrifically-inefficient code. Once so compiled, it is then run on itself to produce a reasonably-fast compiler. Compare Von Neumann Machine. :D –  BMDan Jul 1 '11 at 1:52

That's what compiler bootstrapping is about (since no one mentioned how it's called =).

the process of writing a compiler (or assembler) in the target programming language which it is intended to compile. Applying this technique leads to a self-hosting compiler.

Many compilers for many programming languages are bootstrapped, including compilers for BASIC, ALGOL, C, Pascal, PL/I, Factor, Haskell, Modula-2, Oberon, OCaml, Common Lisp, Scheme, Java, Python, Scala and more...

The chicken and egg problem

If one needs a compiler for language X to obtain a compiler for language X (which is written in language X), how did the first compiler get written? Possible methods to solving this chicken or the egg problem include:

  • Implementing an interpreter or compiler for language X in language Y. Niklaus Wirth reported that he wrote the first Pascal compiler in Fortran.
  • Another interpreter or compiler for X has already been written in another language Y; this is how Scheme is often bootstrapped.
  • Earlier versions of the compiler were written in a subset of X for which there existed some other compiler; this is how some supersets of Java, Haskell, and the initial Free Pascal compiler are bootstrapped.
  • The compiler for X is cross compiled from another architecture where there exists a compiler for X; this is how compilers for C are usually ported to other platforms. Also this is the method used for Free Pascal after the initial bootstrap.
  • Writing the compiler in X; then hand-compiling it from source (most likely in a non-optimized way) and running that on the code to get an optimized compiler. Donald Knuth used this for his WEB literate programming system...
share|improve this answer
    
Good link that also takes you to en.wikipedia.org/wiki/History_of_compiler_writing. In general, I think the original compilers were written in Assembly Language (en.wikipedia.org/wiki/Assembly_language). Only later did the idea of bootstrapping or self-hosting come about. –  Michael Levy Jun 30 '11 at 17:57
1  
+1 FINALLY! Odd that this is only the third most highly rated answer. Yes, bootstrapping. That's the answer –  Adam Rackis Jun 30 '11 at 18:12

Ultimately all computers operate on binary codes, which are fed into the CPU. These binary codes are perfectly natural for a CPU, but also perfectly useless for human beings. One of the first ways to write a program was by punching holes into cards. The position of the holes represented a particular bit position within a word, and the presence or absence of the hole was interpreted as a zero or a one. These cards were put into the right sequence in a box, and then fed into a card reader, which effectively converted them into binary code for the CPU (and your life was effectively forfeit if you dropped the box).

Obviously the very first programmers worked out the binary codes one by one and had a machine to punch the cards. This is essentially assembly language programming on your hands and knees. Once you have that, you can create all the other stuff from it: a simple text editor, an assembly language compiler (to convert the text assembly statements into binary codes), a linker and a loader. And the rest, as they say, is history.

share|improve this answer
4  
Before cards you had a set of switches for the address, a set for the data word and a switch to load the data. You programmed each memory address individually by setting the address and data switches with the binary representation and flicked the load switch on then off. It took ages but the program was only a few words long - bytes had not been invented then. –  Ian Jun 30 '11 at 12:35
4  
...And before that, you had to rewire it. Funfunfun! –  Michael K Jun 30 '11 at 13:23
    
Yes, but when you had to do that, it wasn't really what we'd think of as a modern computer, as the Von Neumann architecture hadn't been invented yet. –  Dave Markle Jul 4 '11 at 13:22

A little googling turns up EDSAC Initial Orders from the late 40s. Since it was the first assembler, it was probably coded in machine language.

Later came assemblers for other machines, like SOAP I and II for the IBM 650. SOAP I was also probably coded in machine language, though I haven't found the definitive statement.

A little later came Fortran (formula translator), for the IBM 704. Presumably it was written in assembler for the 704. An early assembler for the 701 is credited to Nathan Rochester.

If you want to get an idea how to program a computer in machine language, check out one of my favorite sites, Harry Porter's relay computer.

share|improve this answer
    
Holy crap, the Harry Porter (almost said harry potter lol) homebuilt computer is AWESOME. I wish I understood how something like that was built :(. –  Mercfh Jun 30 '11 at 14:58
    
@Sauron: Harry Porter would like nothing better than to tell you. Off that page he's got a beautifully-crafted powerpoint explaining it all. It does assume some basic knowledge of circuitry, but that's not too hard to get. –  Mike Dunlavey Jun 30 '11 at 16:14
    
I know Im just messin ^_^, regardless it's a very impressive machine and im sure many wizard hours were put into it :). –  Mercfh Jun 30 '11 at 17:43

Assuming you're starting with a bare instruction set and nothing else, you'd start by creating a minimal, just-barely-functional assembler or compiler that can load a file, parse a minimal subset of the target language, and generate an executable file as output, by writing the raw machine code using a hex editor or similar.

You'd then use that just-barely-functional compiler or assembler to implement a slightly more capable compiler or assembler that can recognize a larger subset of the target language. Lather, rinse, repeat, until you have the final product.

share|improve this answer

It is not so difficult, as it seems. In the childhood ;) I made some x86 disassembly in mind.

You even don't need to learn it especially. It just happen, when you're able to program in ASM and then trying to fix a third-party binary using interactive disassemblers. Or when writing your own protection with code encryption.

I.e. sometimes you're migrating even from language to codes with no wonder.

share|improve this answer

The first compilers were implemented using assembly language. And the first assemblers were implemented by coding programs in binary ...


It is not THAT long ago that programming in binary was still a skill that people used.

When I was an undergraduate, I remember doing a programming exercise that entailed writing a tiny program in PDP-8 (I think) machine code, entering it via the front panel switches, and running it. I couple of years later, I bought myself a 6502 system development kit that had a hex keypad for entering programs ... and 4k bytes of RAM.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.