Programming Languages and Translators
Levels of Programming Language
Programs can be written at different levels of abstraction. Low-level languages are close to the hardware — they reflect the actual instructions a processor understands. High-level languages are closer to human language — they are more readable and portable.
| Low-level language | High-level language | |
|---|---|---|
| Closeness to hardware | Very close — mirrors processor instructions | Abstract — hides hardware detail |
| Readability | Difficult for humans to read and write | Closer to English — much easier to read |
| Portability | Tied to a specific processor or family | Generally runs on many different machines |
| Execution | Runs very fast — little or no translation needed | Requires translation before execution |
| Examples | Machine code, assembly language | Python, Java, C#, VB.NET |
Most programs — including all software you use daily — are written in high-level languages. Low-level languages are used when precise hardware control or maximum execution speed is required.
"Level" refers to how close the language is to the hardware (low) or to human language (high). A lower level means fewer abstractions between the code and the physical machine.
Machine Code
Machine code is the lowest level of programming language. It consists entirely of binary — sequences of 0s and 1s that the processor can execute directly.
Key properties of machine code:
- Written and stored in binary
- The CPU executes machine code directly without any translation
- Every processor type has its own specific set of machine code instructions — code written for one processor family will not run on a different processor family
- Extremely fast to execute because no translation step is needed
- Very difficult for humans to write or read — a single instruction may be
10110000 01100001in binary
Example — a conceptual machine code instruction in binary:
10110000 01100001
This is meaningless to a human reader without knowing the specific processor's instruction set. Writing entire programs in machine code is impractical — a simple task requires many such instructions.
All programs written in higher-level languages must ultimately be translated into machine code before the CPU can execute them.
Assembly Language
Assembly language is a low-level language that uses short, human-readable codes called mnemonics to represent machine code instructions. Each assembly instruction corresponds to exactly one machine code instruction — this is called a 1:1 correspondence.
Example assembly-like instructions:
| Assembly mnemonic | Meaning |
|---|---|
MOV A, 5 | Move the value 5 into register A |
ADD A, B | Add the value in register B to register A |
CMP A, 10 | Compare the value in register A to 10 |
JMP loop | Jump to the instruction labelled loop |
Assembly language is still low-level — each line maps directly to a single processor instruction — but it is significantly easier for humans to read and write than raw binary.
When assembly language is used:
- Programming embedded systems where the hardware has very limited resources (e.g. a microcontroller in a washing machine)
- Writing code that directly controls specific hardware components (e.g. device drivers)
- Situations where every CPU instruction must be controlled precisely for maximum performance
Assembly language is processor-specific — code written for one architecture (e.g. ARM) will not run on a different architecture (e.g. x86) without being rewritten.
High-Level Languages
High-level languages are designed to be written and understood by humans. They use English-like syntax and hide the underlying hardware entirely from the programmer.
Properties:
- Code is readable and closer to human language:
if score >= 40: print("Pass")is understandable without knowing anything about the hardware - Portable — the same source code can run on different processors and operating systems, because a translator handles the hardware-specific details
- A single high-level statement may compile into many machine code instructions
- Most computer programs — from mobile apps to web servers — are written in high-level languages
Advantages over low-level languages:
| Advantage | Explanation |
|---|---|
| Easier to write | Closer to natural language — programmers can focus on logic, not hardware |
| Easier to maintain | Code can be read and modified by any programmer familiar with the language |
| Portable | Runs on different hardware without rewriting the code |
| Faster to develop | High productivity — one line of high-level code replaces many machine code instructions |
Disadvantage: High-level code cannot run directly on hardware — it must first be translated. This translation step takes time, and the resulting machine code may be slightly less optimal than hand-written low-level code.
Something not quite clicking?
Ask Aica to explain any part of this differently. Free, takes 30 seconds.
Translators: Compiler, Interpreter and Assembler
Because CPUs only execute machine code, any program written in a high-level or assembly language must be translated before it can run. There are three types of translator:
Assembler — translates assembly language into machine code. Each assembly instruction becomes exactly one machine code instruction (1:1 correspondence). Used specifically for assembly language programs.
Compiler — translates an entire high-level language program into machine code before execution, producing a standalone executable file. The original source code is not needed to run the compiled program.
| Compiler | |
|---|---|
| Translates | Entire program before execution |
| Output | A machine code file that runs directly |
| Speed during development | Slower — errors are only reported after the full compilation |
| Execution speed | Fast — the translation has already been done |
| Source code needed at runtime | No |
Interpreter — translates and executes a high-level program one statement at a time. It does not produce a separate machine code file. Instead, it calls appropriate machine code routines within its own code to carry out each statement as it is reached.
| Interpreter | |
|---|---|
| Translates | One statement at a time, during execution |
| Output | No separate machine code file |
| Speed during development | Faster feedback — stops and reports an error at the exact line where it occurs |
| Execution speed | Slower — translation happens every time the program runs |
| Source code needed at runtime | Yes |
Comparison:
| Property | Compiler | Interpreter | Assembler |
|---|---|---|---|
| Language translated | High-level | High-level | Assembly |
| Translation timing | Before execution | During execution | Before execution |
| Machine code file produced | Yes | No | Yes |
| Error reporting | After full compilation | At the failing line | After full assembly |
| Execution speed | Fast | Slower | Fast |
Choosing a Translator
Use an assembler when writing assembly language programs — there is no choice.
Use a compiler when:
- The program will be distributed and run by end users who should not have access to the source code
- Execution speed is critical (compiled code runs faster)
- The program is complete and no longer being actively debugged
Use an interpreter when:
- Developing and testing code — errors are reported immediately at the failing line, making debugging faster
- Writing scripts that run in environments where an interpreter is already installed (e.g. Python scripts)
- The same source code needs to run on multiple different platforms without recompiling
In practice, many modern languages use a combination: source code is compiled to an intermediate bytecode, which is then interpreted by a virtual machine. Python compiles to bytecode (.pyc files), which the Python interpreter then executes. AQA 8525 does not require knowledge of this — just the three translator types above.
Common Exam Mistakes
1. Stating that interpreters produce machine code
An interpreter does not produce machine code directly. It calls machine code subroutines within its own code to execute each statement. A compiler produces a machine code file; an interpreter does not.
2. Claiming machine code is portable
Machine code is entirely specific to a processor or processor family. Code compiled for one CPU cannot run on a different CPU with a different instruction set. High-level languages with a compiler or interpreter achieve portability; machine code does not.
3. Confusing assembly with machine code
Assembly language uses human-readable mnemonics (MOV, ADD, JMP). Machine code is binary. They have a 1:1 correspondence — every assembly instruction maps to one machine code instruction — but they are not the same thing. An assembler translates between them.
4. Saying interpreters are always better for debugging
Interpreters are better for finding errors quickly — they stop at the exact failing line. But compiled programs run faster and do not require the source code to be present at runtime. Neither is universally better; the choice depends on the situation.
5. Forgetting that machine code is specific to a processor family
Machine code is not universal. Code compiled for one type of processor (e.g. Intel x86) will not run on a different type (e.g. ARM). This is why high-level languages with translators are preferred for software that needs to run on multiple devices.
Generate revision on any topic you study
Type any topic you're studying and Aicademy generates a complete lesson, quiz, and flashcard set — personalised to your level.
Lessons on anything
Structured, level-matched lessons on any topic you study
Practice quizzes
Find out what you actually know before the exam does
Flashcard sets
Lock in key concepts with instant revision cards
Ask Aica
Stuck on something? Get a clear explanation, any time
Boolean Logic: Gates and Truth Tables
The Fetch-Decode-Execute Cycle
Related lessons
6 Slides
Software Classification: System Software and Applications
GCSE Computer Science · AQA 8525
4 days ago
7 Slides
7 Slides