In early stored-program computers, the programmer had to get programs into memory by flipping binary switches on the front panel. A little later, came the idea that you could punch your machine-code program onto cards, as numbers, and then write another program that would read the cards into memory. So my program would be entered as a sequence of cards:
0 4107 1 4200 2 4805and so on.
This is better than flipping switches. But it would be even better to have some mnemonics.
0 CLR 07 ; This is where we store the sum. 1 RD 2 JIZ 05 ; Will stop and print if 0 typed. 3 ADD 07 4 GO 01 5 PRT 07 6 STOP 7 DATA 3458Programmers soon developed the techniques to read and decode such mnemonic commands. This type of notation is called assembler or assembly code and the program that translates it is also called an assembler.
This still leaves the programmer worrying about where to put each
instruction. He has to allocate all the addresses manually. And if he
wanted (e.g.) to insert another instruction before the PRT
, he'd
have to change the 5 to a 6, the 07 to an 08, the 6 to a 7, ....
So the next stage in evolution was to have a cleverer assembler that
could accept names for labels and variables, allocating
these to addresses by itself.
DATA I INITIAL I 3458 PROGRAM START 0 CLR I ; This is where we store the sum. NEXT: RD JIZ OUT ; Will stop and print if 0 typed. ADD I GO NEXT OUT: PRT I STOP
But that still means you have to break down your calculations into individual instructions. So the next step was to design a program called a compiler which could do this for you. This was the start of high-level languages like Fortran (one of the first) and Pascal. This is what how the program might look if written in such a language.
integer N, Sum; Sum := 0; Next: read(N); if N=0 then goto Out; Sum := Sum + N; goto Next; Out: print(Sum);