Section
01 Part 04 – Registers |
“Life
is like a cash register, in that every account, every thought, every deed, like every sale, is registered and recorded.” ~ |
Introduction
Processors
have memory spaces called registers, and different processors have different types
of registers for different reasons.
They’re used for moving, adding, subtracting, numbers quickly and
effectively to and from places. We’re
going to look at the common 16 registers of the 68k and what they can do.
Data
Registers
The
68k has 8 “data” registers, and are named:
d0, d1, d2, d3, d4, d5, d6 and d7 |
“Data
registers” are used for storing and changing numbers mathematically, each
register has a long-word of space:
register name |
space (in hexadecimal) |
d0 |
00 00
00 00 |
d1 |
00 00
00 00 |
d2 |
00 00
00 00 |
d3 |
00 00
00 00 |
d4 |
00 00
00 00 |
d5 |
00 00
00 00 |
d6 |
00 00
00 00 |
d7 |
00 00
00 00 |
Using
the previous instruction as an example:
move.w #$04F0,d0 |
This
will move the word 04F0 into data register d0, after the instruction is
processed by the 68k, d0
will contain 00
00 04 F0.
You
can perform byte, word and long-word instructions on any of them at any time,
and you can use most instructions on them, but we’ll get into them in more
detail later.
Address
Registers
The
68k has another set of 8 registers called “address” registers, and are named:
a0, a1, a2, a3, a4, a5, a6 and a7 |
“Address
registers” also have long-word spaces each:
register name |
space (in hexadecimal) |
a0 |
00 00
00 00 |
a1 |
00 00
00 00 |
a2 |
00 00
00 00 |
a3 |
00 00
00 00 |
a4 |
00 00
00 00 |
a5 |
00 00
00 00 |
a6 |
00 00
00 00 |
a7 |
00 00
00 00 |
They
can be used in much the same way as data registers, except, you cannot perform byte
instructions on them (only word or long-word), and some instructions that work
on data registers, will not work on address registers, but we’ll get into those
details later on.
These
registers are used for storing addresses (i.e. offsets), and can write to or
read from those offsets, for example:
movea.l #$00000039,a0 |
This
will put the long-word 00000039 into a0, a0 will now contain 00000039, now that is pretty much the
same as a data register, but now that we have the long-word inside a0, we can use it to our
advantage:
move.b #$44,(a0) |
You’ll
notice that with this instruction, a0
is inside brackets, this will tell the 68k that instead of moving 44 into a0, it should move it to memory
at the offset inside a0,
a0 contains 00000039, so this instruction will put
44 into memory at the offset 00000039:
Offset |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
C |
D |
E |
F |
00000000 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00000010 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00000020 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00000030 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
44 |
00 |
00 |
00 |
00 |
00 |
00 |
etc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
As
you can see, a0 acts as a gateway to memory.
The
“address registers” have other features too, such as “indexing”, for example
(and we’ll pretend that a0
still has 00000039 inside of it):
move.b #$9B,$04(a0) |
The
$04 you see right before the bracket, is the index value, this will add to the
offset inside a0 to give you a new
offset. So a0 contains 00000039, you add the 04 which gives
you 0000003D, so, 9B is moved to offset 0000003D:
Offset |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
C |
D |
E |
F |
00000000 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00000010 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00000020 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00000030 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
9B |
00 |
00 |
etc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Here’s
another example to clarify:
movea.l #$00000010,a0 move.b #$20,$01(a0) move.b #$40,$02(a0) move.b #$F0,$0F(a0) move.b #$0E,(a0) |
So, 00000010 is moved into a0, 20 is moved to 00000010 plus 01, 40 is moved to 00000010 plus 02, F0 is moved to 00000010 plus 0F, and 0E is moved to 00000010 directly, which gives us:
Offset |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
C |
D |
E |
F |
00000000 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00000010 |
0E |
20 |
40 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
F0 |
00000020 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00000030 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
etc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Auto
Increment/Auto Decrement
Another
feature is auto increment and auto decrement, observe:
movea.l #$00000020,a0 move.b #$B5,(a0)+ move.b #$11,(a0)+ |
You’ll
notice the + symbols on the right end of the brackets, this is auto increment.
As
you can see, once the byte has been written to the address, a0 is increased by
1.
Here’s
another example, using word:
movea.l #$00000020,a0 move.w #$A90E,(a0)+ |
The
reason why it increases by 2 this time, is because we moved a “word” of data, a
word is 2 bytes. If we moved a long-word,
it would have incremented by 4, because a long-word is 4 bytes.
Auto
decrement is similar, but in reverse:
movea.l #$00000020,a0 move.b #$2E,-(a0) |
You’ll
notice in this example, there’s a – symbol, and instead of being on the right
side, it is on the left side
For
decrement, the address register is always decreased before the instruction moves the number.
And
there you have it. There are other
indexing methods used with address registers, but that’s better left for
another later part.