These are actually quite fun.

Machines run machine code.

But writing machine code is not particularly pleasant. It's very fiddly, and easy to get wrong. Unfortunately, machines run machine code, not other forms of code. Grace Hopper pioneered a solution to this problem; she worked out that it was possible to design other forms of code, which were easier to write certain classes of problems (e.g. code for processing financial transactions, which doesn't need exact control ove how every bit is layed out on the machine) and then "translate" that code into machine code.

This is the essence of a compiler. It turns programs into machine code.

program -> compiler -> machine code

There are also "interpreters". Instead of feeding in the entire program and then generating the appropriate machine code, they start with the entry point (maybe the first line) of the program, and then run all the lines of the program whenever it needs to.

practice questions

  1. Which of these descriptions would apply to a compiler?
    • A: runs through a program line by line, and runs each line as soon as it reads it
    • B: takes an entire program and translates it in its entirety into machine code, which can then be executed
    • C: takes a series of abbreviations for specific machine code instructions and replaces them with the corresponding machine code
  2. Consider the program below, and decide (with a reason for each) which of a compiler, assembler or interpreter you could use in order to run it.
function f(x)
	return x * x
endfunction
  1. Consider this program (taken from this resource) and explain whether an assembler would be a suitable device to translate it.
; ----------------------------------------------------------------------------------------
; Writes "Hello, World" to the console using only system calls. Runs on 64-bit Linux only.
; To assemble and run:
;
;     nasm -felf64 hello.asm && ld hello.o && ./a.out
; ----------------------------------------------------------------------------------------

          global    _start

          section   .text
_start:   mov       rax, 1                  ; system call for write
          mov       rdi, 1                  ; file handle 1 is stdout
          mov       rsi, message            ; address of string to output
          mov       rdx, 13                 ; number of bytes
          syscall                           ; invoke operating system to do the write
          mov       rax, 60                 ; system call for exit
          xor       rdi, rdi                ; exit code 0
          syscall                           ; invoke operating system to exit

          section   .data
message:  db        "Hello, World", 10      ; note the newline at the end

Note – if you would like solutions you can try the exercises in a self-marking form on stepik.org.

further reading