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 am reading the book The Elements of Computing Systems: Building a Modern Computer from First Principles, which contains projects encompassing the build of a computer from boolean gates all the way to high level applications (in that order). The current project I'm working on is writing an assembler using a high level language of my choice, to translate from Hack assembly code to Hack machine code (Hack is the name of the hardware platform built in the previous chapters). Although the hardware has all been built in a simulator, I have tried to pretend that I am really constructing each level using only the tools available to me at that point in the real process.

That said, it got me thinking. Using a high level language to write my assembler is certainly convenient, but for the very first assembler ever written (i.e. in history), wouldn't it need to be written in machine code, since that's all that existed at the time?

And a correlated question... how about today? If a brand new CPU architecture comes out, with a brand new instruction set, and a brand new assembly syntax, how would the assembler be constructed? I'm assuming you could still use an existing high level language to generate binaries for the assembler program, since if you know the syntax of both the assembly and machine languages for your new platform, then the task of writing the assembler is really just a text analysis task and is not inherently related to that platform (i.e. needing to be written in that platform's machine language)... which is the very reason I am able to "cheat" while writing my Hack assembler in 2012, and use some preexisting high level language to help me out.

share|improve this question

migrated from stackoverflow.com Jan 8 '12 at 20:29

This question came from our site for professional and enthusiast programmers.

14  
You can always write a cross-compiler and use that to produce a code for new hardware nowadays. –  Kerrek SB Jan 8 '12 at 20:26
    
@PersonalNexus Thanks for that, snafu edit on my part. –  Yannis Rizos Jan 8 '12 at 20:41
1  
@YannisRizos No problem, happens to the best of us :) –  PersonalNexus Jan 8 '12 at 20:42
6  
It is possible that first assembler might have been written in assembly on a piece of paper. Conversion to machine code might then have been performed still on paper and burned to some sort of ROM with switches, one word at a time. –  mouviciel Jan 9 '12 at 8:29
    
My first computer was a ZX81, with 1KB RAM, so my (admitedly short) machine code programs were in fact hand-translated. –  user281377 Jan 12 '12 at 14:45

11 Answers 11

up vote 25 down vote accepted

for the very first assembler ever written (i.e. in history), wouldn't it need to be written in machine code

Not necessarily. Of course the very first version v0.00 of the assembler must have been written in machine code, but it would not be sufficiently powerful to be called an assembler. It would not support even half the features of a "real" assembler, but it would be sufficient to write the next version of itself. Then you could re-write v0.00 in the subset of the assembly language, call it v0.01, use it to build the next feature set of your assembler v0.02, then use v0.02 to build v0.03, and so on, until you get to v1.00. As the result, only the first version will be in machine code; the first released version will be in the assembly language.

I have bootstrapped development of a template language compiler using this trick. My initial version was using printf statements, but the first version that I put to use in my company was using the very template processor that it was processing. The bootstrapping phase lasted less than four hours: as soon as my processor could produce barely useful output, I re-wrote it in its own language, compiled, and threw away the non-templated version.

share|improve this answer
1  
Have you still got all the phases? I would love to see them, and compare them against eachother. Just to get a feel for the process you went through. –  Marjan Venema Jan 8 '12 at 21:17
2  
@MarjanVenema No, I don't have them any longer - I built it in 1998, and kept using it until 2005, when I discovered StringTemplate. I was overwriting the previous phase with the next as I was working towards the initial usable version. My development cycle consisted of coding new stuff, running the code generator to build itself in a separate directory, running diff against the current code generator to see that the generated portion of code did not change in an unexpected way, replacing the code in place, and running it once more to finish the cycle. –  dasblinkenlight Jan 9 '12 at 1:27
    
Pity but understandable :) Thanks for describing what you did (and for the link). –  Marjan Venema Jan 9 '12 at 6:59
2  
I would think you need to keep some sort of bootstrapping chain. Machine Code => Limited ASM => Full ASM => Some Language. Otherwise, if you loose your binary any step along the way you'll be screwed. (Alternately you could have a C cross-compiled version, since realistically not all C compiler binaries will disappear at once.) –  edA-qa mort-ora-y Jan 9 '12 at 14:07
    
@MarjanVenema: "Bootstrapping a simple compiler from nothing" sounds pretty similar -- see stackoverflow.com/questions/13537/bootstrapping-a-language for some discussion. –  David Cary Aug 16 '12 at 10:19

I presume that the first assemblers were written in machine code, because as you say, nothing else was available back then.

Today, however, when a brand new CPU architecture comes out, we use what is known as a Cross-Compiler, which is a compiler that produces machine code not for the architecture on which it is running, but for a different architecture.

(As a matter of fact, as I am sure you will find out later on in the book you are reading, there is absolutely nothing which makes a compiler inherently more suitable for producing machine code for the architecture on which it is running than on any other architecture. It is just a matter of which architecture you, as the creator of the compiler, are going to target.)

So, today it is even possible (at least in theory) to create a brand new architecture and have high-level language compilers natively running on it (compiled on other architectures using cross-compilers) before you even have an assembler for that architecture.

share|improve this answer

It's hard to be certain about the very first assembler (hard to even define what that was). Years ago, when I wrote a few assemblers for machines that lacked assemblers, I still wrote the code in assembly language. Then, after I had a section of code reasonably complete I translated it into machine code by hand. Those were still two entirely separate phases though -- when I was writing the code, I wasn't working or thinking at a machine-code level at all.

I should add that in a few cases, I went a step further: I wrote most of the code in an assembly language I found simpler to use, then wrote a tiny kernel (more or less what we'd now call a virtual machine) to interpret that on the target processor. That was deathly slow (especially on a 1 MHz, 8-bit processor), but that didn't matter much, since it normally only ran once (or at most, a few times).

share|improve this answer

At first "assembly" was written on paper and then manually "compiled" onto punch cards.

My grand father was working with a ZRA1 (sorry, page only exists in German, but the Google translation is ok to the point where you can actually pick up the most important facts :D).
The modus operandi was to write down your code on paper in a sort of assembly language and the secretary would actually do the transcription to punch cards, then pass them to the operator and the result would be handed back the morning after.

All this was essentially before programmers had the luxury of inputting data through a keyboard and view it on a screen.

share|improve this answer
    
When I was studying at the university, they still had the paper blocks used to write machine code. You write the program on the right, there are columns on the left to translate the instructions to hexadecimal. And a column for the current address. The first assemblers were actually human. –  Florian F Nov 9 at 16:02

According to Wikipedia, the first ever assembler / assembly language was implemented for the IBM 701 by Nathaniel Rochester in circa 1948. Prior to that, all programming was done in machine language. So it follows that the first assembler was written in machine code.

This pattern (writing initial versions of assemblers in machine code) probably continued for a number of years. However, these days assemblers and compilers are written in higher level languages, and an assembler or compiler for a new machine architecture is typically developed on a different architecture and cross-compiled.

(FWIW - writing and debugging non-trivial programs in machine code is an exceedingly laborious process. Someone developing an assembler in machine code would most likely bootstrap to an assembler written in assembler as soon as possible.)

This Wikipedia page on bootstrapping compilers and assemblers is worth a read ... if this is all baffling to you.

share|improve this answer

The first assemblers were probably written in assembly language and then hand assembled into machine code. Even if the processor had no official 'assembly language' then programmers probably did most of the job of programming using some kind of pseudo code before translating that code into machine instructions.

Even in the earliest days of computing, programmers wrote programs in some kind of symbolic notation and translated them into machine code before feeding it into their computer. In Ada's case, she would have translated them into punched cards for Babbage's Analytical Engine, but alas it was never built.

The first computer I owned was a Sinclair ZX81 (Timex 1000 in the US). The back of the manual had all of the information you needed to translate Z80 assembly language into machine code (including all of the weird index mode opcodes the Z80 had).

I would write out a program (on paper) in assembly language and dry-run through the code. When I was happy that my program was bug-free, I would look up each instruction in the back of the manual, translate it into machine code and write the machine code down on the paper too. Finally I would type all of the machine code instructions into my ZX81 before saving it to tape and trying to run it.

If it didn't work, I would double check my hand assembly and if any translation was wrong I would patch the bytes loaded from tape before re-saving it and trying again to run the program.

From experience, I can tell you that it is much easier to debug your code if it is written in assembly language than in machine code - hence the popularity of disassemblers. Even if you don't have an assembler, hand assembling is less error prone than trying to write machine code directly, though I guess Mel might disagree. *8')

From the introduction to The Story of Mel, a Real Programmer (May 1983):

A recent article devoted to the macho side of programming made the bald and unvarnished statement:

Real Programmers write in Fortran.

Maybe they do now, in this decadent era of Lite beer, hand calculators and "user-friendly" software but back in the Good Old Days, when the term "software" sounded funny and Real Computers were made out of drums and vacuum tubes, Real Programmers wrote in machine code. Not Fortran. Not RATFOR. Not, even, assembly language. Machine Code. Raw, unadorned, inscrutable hexadecimal numbers. Directly.

Lest a whole new generation of programmers grow up in ignorance of this glorious past, I feel duty-bound to describe, as best I can through the generation gap, how a Real Programmer wrote code. I'll call him Mel, because that was his name.

...

share|improve this answer

There is no difference then or now. You want to invent a new programming language, you choose one of the languages available to you today to make the first compiler. over some period of time, if it is a goal of the project, you create a compiler in that language and it can then self-host.

If all you had was pencil and paper and some switches or punch cards as your user interface to the first or next new instruction set, you used one or all of the items available to you. You could very well have written an assembly language, on paper, and then used an assembler, you, to convert it into machine code, maybe in octal, then at some point that went into the interface to the machine.

When a brand new instruction set is invented today, no different, depending on the company/individuals, practices, etc. it is quite likely that the hardware engineer probably programming in verilog or vhdl, writes the first few test programs by hand in machine code (probably in hex or binary). depending on the software teams progress they may very quickly or not for a very long time coming switch to assembly language and then a compiler.

The first computing machines were not general purpose machines that you could use to create assemblers and compilers from. You programmed them by moving some wires between the output of the prior alu to the input of the next. Eventually you had a general purpose processor such that you could write an assembler in assembly, hand assemble it, feed it in as machine code, then use that to parse ebcdic, ascii, etc. and then self-host. store the binary to some media that you could later read/load not having to keep flipping switches to hand feed machine code.

Think of punch cards and paper tape. Instead of flipping switches you could most definitely make a completely mechanical machine, a labor saving device, that created the media the computer would read. Instead of having to enter the machine code bits with switches like an altair you could instead feed paper tape or punch cards (using something mechanical, not processor driven, that fed the memory or processor, OR using a small machine code written boot loader). This was not a bad idea because you could make something, driven by the computer that could also mechanically produce the paper tapes or punch cards, and then feed those back in. Two sources of punch cards, the non-computer based mechanical labor saving device, and the computer driven machine. both produce the "binaries" for the computer.

share|improve this answer
1  
+1 for the "assembler, you" comment. It's easy to get attached to one definition of a word (i.e. assembler = software) but your comment really puts the obvious back into perspective... that the "assembly process" is just a system/routine, one which easily could be undertaken by a human assembler. –  The111 Jan 13 '12 at 9:53
1  
also folks keep getting stuck on this idea that early computers had instruction sets. The early computers were women with good math skills with pencil and paper, and that is what they were called, computers. then those women (or one in particular) programmed the eniac by connecting wires not using an instruction set. Programming with an instruction set was well well down the road. Yes, very easy to get caught up in the use of a word or term like assembler or computer or early. –  dwelch Jan 13 '12 at 15:55

There are one or two instances in Brook's computer zoo where he said something like "the mnemonics are our invention, the designer simply used numeric opcode or the character whose code was the opcode", so there where machines for which there wasn't even an assembly language.

Entering programs end debugging at the front panel (for those who haven't done it, it was a way to set up the memory, you set some switches to the address, some others to the value and pressed a button, or another button to read the value) was common far later. Some old timers brag they would still be able to enter the boot code for machines they used extensively.

The difficulty of writing directly machine code and reading programs from memory dump is quite dependent on the machine language, some of them are relatively easy (the hardest part is tracking the addresses), x86 is one of the worse.

share|improve this answer
    
The pdp-11 didn't even have the luxury of knobs. You could alter storage by entering the binary address on 8 toggle switches, and, the value on 16 toggle switches then press the button. I actually saw someone fix a looping program this way! –  James Anderson Jan 13 '12 at 6:20

I built a computer in 1975. It was very advanced over its contemporary the Altair, because it had a 'monitor rom' which let me enter programs by typing in machine code in hex and viewing this code on a video monitor, where as with the Altair each machine instruction had to be entered a bit at time using a row of switches.

So yes, in the early days of computers and then again in the early days of personal computers people did write applications in machine code.

share|improve this answer

An anecdote:

When I learned assembly language, on the Apple ][, There was a program included in the ROM called the micro-assembler. It did immediate translation of assembly instruction to bytes, as you entered them. This means there were no labels -- if you want to jump or load, you had to calculate the offsets yourself. It was much easier than looking up the instruction layouts and entering hex values though.

No doubt, real assemblers were first written using the micro-assembler, or some other not quite complete environment.

share|improve this answer

I don't know the history of it but assembly isn't very hard to learn. I can't imagine it being difficult to write an assembler (and i have seen people do it). From my understanding you would have a (pricy) disk drive, monitor, keyword and a tape.

With an assembly and the ability to save on disk/tape it isnt hard to write a parser. Many university students write parsers in assembly for their course. Not for compiling but for transformation from one format to another. After writing a parser it isnt hard to write a compiler.

share|improve this answer

protected by gnat Nov 9 at 15:18

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

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