Version without JavaScript, read-only: workshops, quizzes and running code are not available here. Full version · Catalogue · Sign in
Lecture notes · chapter 2
The 68000 and its first instructions
The processor's registers, the shape of a program, the instructions that move and compute, and the flags that sum up each result.
What is inside the processor
Registers
A register is a small memory cell inside the processor, much faster than main memory. The 68000 has:
| Registers | Size | Role |
|---|---|---|
D0 to D7 | 32 bits | data registers: this is where we compute |
A0 to A6 | 32 bits | address registers: they hold addresses, to point into memory |
A7, alias SP | 32 bits | the stack pointer (chapter 5) |
PC | 32 bits | the program counter: the address of the next instruction |
SR | 16 bits | the status register; its low byte is the CCR, which holds the flags |
The execution cycle
The program is in memory, like the data. The processor endlessly repeats three steps:
- fetch the instruction at the address held in
PC; - decode what it asks for, and move
PCon to the next instruction; - execute the instruction.
A jump (chapter 4) is nothing more than an instruction that writes a new address into PC.
The shape of a program
A line
Each line has at most four fields, separated by spaces:
BOUCLE ADD.W D1,D0 ; D0 <- D0 + D1
- a label (
BOUCLE), in the first column, which gives a name to the address of the line; - the instruction code, with its size (
ADD.W); - the operands, source first, destination second (
D1,D0); - a comment, after
;(or a whole line starting with*).
Directives
Some lines are not processor instructions but orders given to the assembler, the program that translates the text into machine code:
| Directive | Effect |
|---|---|
ORG $1000 | the code that follows is placed from address $1000 onwards |
N EQU 10 | gives the name N to the value 10 (no room in memory) |
X DC.W 12 | reserves a word, initialised to 12, at the address named X |
T DC.B 'Bonjour',0 | reserves initialised bytes: a string terminated by 0 |
R DS.L 1 | reserves a long word, not initialised |
END START | end of the text; execution starts at the label START |
A first program
ORG $1000
START MOVE.W VAL1,D0 ; D0 <- VAL1
ADD.W VAL2,D0 ; D0 <- D0 + VAL2
MOVE.W D0,SOMME ; SOMME <- D0
SIMHALT ; stop the simulator
VAL1 DC.W 12
VAL2 DC.W 30
SOMME DS.W 1
END STARTThis is a workshop: you can edit the code, then run it all at once or step by step, watching the registers change (they light up) and the memory at the chosen label. The program stores 42 in SOMME (the sum). The data are placed after the code, but that is only a habit: for the processor, everything is just bytes in memory. SIMHALT is specific to the Easy68K simulator: it stops execution. Without it, the processor would carry on and try to execute the data.
The first instructions
Moving
| Instruction | Effect |
|---|---|
MOVE.t src,dst | copies src into dst |
MOVEQ #n,Dk | loads a small integer (from −128 to 127) into Dk, on 32 bits; faster |
CLR.t dst | sets dst to zero |
EXG Di,Dj | swaps two registers |
The .t is the size: .B, .W or .L. The # marks an immediate value: MOVE.W #12,D0 stores the number 12, whereas MOVE.W 12,D0 would read the word located at address 12.
Computing
| Instruction | Effect |
|---|---|
ADD.t src,dst | dst ← dst + src |
SUB.t src,dst | dst ← dst − src |
ADDQ.t #n,dst, SUBQ.t #n,dst | adds or subtracts a small constant, from 1 to 8 |
NEG.t dst | dst ← −dst |
EXT.W Dk, EXT.L Dk | sign-extends a byte to a word, a word to a long word |
MULU.W src,Dk | unsigned multiplication: word × word, 32-bit result in Dk |
MULS.W src,Dk | the same, signed |
DIVU.W src,Dk | unsigned division of the long word Dk by the word src: quotient in the low word of Dk, remainder in the high word |
DIVS.W src,Dk | the same, signed |
Bit operations
| Instruction | Effect |
|---|---|
AND.t, OR.t, EOR.t | and, or, exclusive or, bitwise |
NOT.t dst | inverts all the bits |
LSL.t #n,Dk, LSR.t #n,Dk | logical shift left, right, by 1 to 8 positions; the vacated bits are 0 |
ASR.t #n,Dk | arithmetic shift right: the sign bit is copied |
Shifting one position to the left multiplies by 2; to the right, divides by 2. LSR for an unsigned number, ASR for a signed one: ASR.B #1 on $F6 (−10) gives $FB (−5), whereas LSR.B #1 would give $7B (123).
The flags
After most instructions, the CCR sums up the result in five bits:
| Flag | Name | Is 1 when |
|---|---|---|
N | negative | the most significant bit of the result is 1 |
Z | zero | the result is zero |
V | overflow | the result is wrong as a signed number |
C | carry | there is a carry (or a borrow) as an unsigned number |
X | extend | copies C, for computations done in several pieces |
Not all instructions change them in the same way. ADD and SUB update them all; MOVE updates N and Z and clears V and C; MOVEA and ADDA, which target an address register, leave them alone.
These flags are used by the conditional branches of chapter 4: that is how a program makes a decision.
Printing a result
Easy68K provides input-output services through the TRAP #15 instruction. The service number is in D0; for example, service 3 prints in decimal the signed number held in D1.L:
MOVE.W SOMME,D1
EXT.L D1 ; D1 on 32 bits, sign included
MOVE.B #3,D0 ; service 3: print D1.L
TRAP #15