Welcome to the Language of the Processor
Ever wondered how a computer actually "understands" the code you write in Python or Java? It doesn't see your variables or "if" statements. Instead, it processes a sequence of binary numbers called Machine Code. In this chapter, we are going to explore how we bridge the gap between human logic and hardware reality using Assembly Language and Addressing Modes.
Don't worry if this seems a bit "low-level" or "mathsy" at first. Think of this as learning the secret handshake that lets you talk directly to the CPU's brain!
1. Machine Code: The CPU's Native Tongue
Machine Code is the only language a processor can actually execute. It consists entirely of binary digits (\(0\)s and \(1\)s). Each instruction tells the CPU exactly what to do with its hardware circuits.
While machines love binary, humans find it incredibly difficult to read. Imagine trying to find a bug in a page full of \(01101010011\)! This is why we use Assembly Language.
Key Takeaway: Machine code is the ultimate "low-level" language. It is fast for the computer but nearly impossible for humans to write without mistakes.
2. Assembly Language: Mnemonics to the Rescue
To make programming easier, we use Assembly Language. This replaces binary bit patterns with short, easy-to-remember words called mnemonics.
For example, instead of writing a binary string for "add these numbers," we might just write ADD. Every Assembly instruction corresponds to exactly one Machine Code instruction. This is why we call it a one-to-one relationship.
Analogy: If Machine Code is a series of precise electrical signals, Assembly Language is like using shorthand notes to describe those signals.
3. The Anatomy of an Instruction
Every instruction in Assembly (and Machine Code) is usually split into two parts:
1. The Opcode (Operation Code): This tells the processor what to do (e.g., Load, Add, Store). According to the AQA specification, the opcode also includes information about which addressing mode to use.
2. The Operand: This tells the processor what data to use, or where to find the data (a memory address).
Quick Review: Opcode = The Action. Operand = The Data/Target.
4. Addressing Modes: How do we find the data?
The CPU needs to know if the number in the operand is the actual value it should use, or just a "pointer" to a location in memory. This is handled by Addressing Modes. For your AQA exam, you only need to know two:
Immediate Addressing
In Immediate Addressing, the operand is the actual value you want to use. You aren't looking anything up in memory; the data is right there in the instruction.
Example: ADD #10 (This tells the CPU to "Add the actual number \(10\)").
Mnemonic Tip: Think of "Immediate" as "I need it right now, and here it is!"
Direct Addressing
In Direct Addressing, the operand is a memory address. The CPU must go to that address in RAM to find the value it needs to use.
Example: ADD 10 (This tells the CPU to "Go to memory location \(10\), see what number is inside, and add that number").
Analogy: Immediate addressing is like having \(\$5\) in your pocket. Direct addressing is like having a piece of paper that says "The \(\$5\) is in Locker number \(10\)."
5. The Standard Instruction Set
The AQA syllabus defines a specific set of operations you should be familiar with. You don't need to memorize every single bit pattern, but you should understand what these mnemonics do:
Data Transfer
LDR (Load): Moves a value from memory into a register.
STR (Store): Moves a value from a register into a memory location.
Arithmetic
ADD: Adds values together.
SUB: Subtracts one value from another.
Logical Operations (Bitwise)
These compare bits one by one:
AND: Result is \(1\) if both bits are \(1\).
OR: Result is \(1\) if either bit is \(1\).
NOT: Flips the bit (from \(0\) to \(1\), or \(1\) to \(0\)).
XOR: Result is \(1\) if the bits are different.
Shifts
These move the bits inside a binary number left or right:
LSL (Logical Shift Left): Moves bits to the left, filling the gaps with \(0\). This effectively multiplies a number by powers of \(2\).
LSR (Logical Shift Right): Moves bits to the right, filling the gaps with \(0\). This effectively divides a number (using integer division).
Control Flow (Branching)
These instructions let the program "jump" to different parts of the code:
CMP (Compare): Compares two values to see if they are equal, greater, or less than each other.
B (Branch): An "unconditional" jump. The program skips to a specific instruction no matter what.
BEQ / BNE: "Conditional" branches. BEQ (Branch if Equal) only jumps if the previous CMP found the values were the same. BNE (Branch if Not Equal) jumps if they were different.
HALT: Stops the program entirely.
6. Common Mistakes to Avoid
1. Forgetting the # symbol: In exam questions, #15 usually means the number \(15\) (Immediate), while 15 means "the data at address \(15\)" (Direct). Look closely at the symbols!
2. Mixing up LDR and STR: Remember, Load brings data into the processor (so you can work on it), and Store sends it out to memory (to save it for later).
3. Shift Confusion: Remember that LSL (Left) makes the number bigger (multiplication) and LSR (Right) makes it smaller (division).
Summary Key Takeaways
Machine Code: Binary instructions the CPU executes directly.
Assembly: Uses mnemonics to represent machine code (one-to-one).
Opcode: The part of the instruction that defines the operation and addressing mode.
Immediate Addressing: The operand is the value.
Direct Addressing: The operand is the address where the value is stored.
Logical Operators: AND, OR, NOT, XOR act on individual bits.
Note: To see how these instructions are actually fetched and executed, check out the chapter on "The processor, registers and the Fetch-Execute cycle".