68000 ASSEMBLY LANGUAGE COURSE PART II by Mark van den Boer
Welcome to part II of this course. In part I, some fundamentals
of the 68000 were shown. In this part, I will show you which
addressing modes the 68000 uses. First an example of addressing
modes which the 6502 and 6809 use:
lda #10 * immediate addressing
lda $10 * zero-page (6502) or direct-page addressing (6809)
inx * inherent (6502)
inca * inherent (6809)
Now, what does a line of code in 68000 assembler look like?
LABEL OPCODE OPER1,OPER2 COMMENT
The meanings of these fields are:
label: A name given to this line of code. Some assemblers
require a : to follow the label-name. This field is
optional.
opcode: This field specifies the operation you wish to perform.
It is the only field that isn't optional. Depending on
the opcode the 68000 expects 0, 1 or 2 operands.
oper1: The first operand to appear with the opcode. The
appearance of this field depends on the specified
opcode.
oper2: The second operand to appear with the opcode. The
appearance of this field depends (surprise, surprise) on
the specified opcode.
comment: Another optional field which is used for commenting all
tricks people put in their programs. Most assemblers
require a * as the first character of the comment field.
The comment field is optional.
Now what does an addressing mode do? An addressing mode specifies
on which data the opcode (instruction) must operate.
The 68000 has a total of 14 addressing modes, all of which now
will explained. As examples in all addressing modes I will use
the MOVE instruction. MOVE can have the .b, .w and .l suffixes as
mentioned in part I of the course. The MOVE instruction moves the
data specified by oper1 to the place specified by oper2. For
example: MOVE.B $1,$2 performs exactly the same operation as the
following 6502 and 6809 code: LDA $1 STA $2.
The addressing modes:
1. Inherent addressing
In this addressing mode there are no operands since they are
already supplied by the opcode.
E.g.: RESET * reset all peripherals
RESET is an 68000 instruction which is used to reset all the
peripherals.
2. DATA REGISTER DIRECT ADDRESSING
Assembler syntax: Dn (n can range from 0 to 7)
In this addressing mode a data register contains the operand.
E.g.:
Instruction Before After
MOVE.B D1,D0 d0=ffffffff d0=ffffff67
d1=01234567 d1=01234567
MOVE.W D1,D0 d0=ffffffff d0=ffff4567
d1=01234567 d1=01234567
MOVE.L D1,D0 d0=ffffffff d0=01234567
d1=01234567 d1=01234567
As you might have noticed, an instruction with .b as a suffix
only changes the lowest 8 bits of the destination, and
instructions with .w as a suffix only change the lowest 16 bits
of the destination. Instructions with .l as a suffix change all
32 bits of the destination.
3. ADDRESS REGISTER DIRECT ADDRESSING
Assembler syntax: An (n can range from 0 to 7)
In this addressing mode an address register contains the operand.
Byte operators (those with .b suffix) are not allowed in this
addressing mode. When using the address register as a destination
and it is a word operation (suffix is .w), the word is sign-
extended into a longword. This means that during a wordtransfer
into a data register the upper 16 bits are filled with the value
of the most-significant bit (this is bit 15) of the word. An
example below will show you how it's done.
E.g.:
Instruction Before After
MOVE.W A1,D0 d0=ffffffff d0=ffff4567
a1=01234567 a1=01234567
MOVE.W D0,A1 d0=01234567 d0=01234567
a1=ffffffff a1=00004567 <- extend!!
MOVE.W D0,A1 d0=0000ffff d0=0000ffff
a1=00000000 a1=ffffffff <- extend!!
MOVE.L A1,D0 d0=ffffffff d0=01234567
a1=01234567 a1=01234567
4. ADDRESS REGISTER INDIRECT ADDRESSING
Assembler syntax: (An) (n between 0 and 7)
In this addressing mode, the address register contains the
address of the operand. In assembler this is being denotated by
putting parentheses around an address registers name, e.g. (a0).
The contents of a0 points to the address where the data has to be
fetched from. When using word (.w) or longword (.l) addressing it
is absolutely necessary that the address register contains an
even number (I will explain the reason for this in a forthcoming
article).
E.g.:
Instruction Before After
MOVE.L (A1),D0 d0=ffffffff d0=01234567
a1=00001000 a1=00001000
address $1000 contains 01234567
MOVE.L D0,(A1) d0=76543210 d0=76543210
a1=00001000 a1=00001000
address $1000 now contains 76543210
5. ADDRESS REGISTER INDIRECT ADDRESSING WITH POST-INCREMENT
Assembler syntax: (An)+ (n between 0 and 7)
This addressing mode resembles the address register indirect
addressing mode. The only difference is that after having fetched
or stored the data, the address register is incremented. The
increment depends on the suffix used in the opcode. If the suffix
is .b then the address register will be incremented by one. If
the suffix is .w then the address register will be incremented by
two (one word is two bytes). If the suffix is .l then the address
register will be incremented by four (one longword is four
bytes). In assembler this addressing mode is denotated by putting
the address register within parentheses followed by a + sign. For
example: (a7)+
E.g.:
Instruction Before After
MOVE.L (A1)+,D0 d0=ffffffff d0=01234567
a1=00001000 a1=00001004
address $1000 contains 01234567
MOVE.W (A1)+,D0 d0=ffffffff d0=ffff0123
a1=00001000 a1=00001002
address $1000 contains 01234567
MOVE.B (A1)+,D0 d0=ffffffff d0=ffffff01
a1=00001000 a1=00001001
address $1000 contains 01234567
MOVE.L D0,(A1)+ d0=76543210 d0=76543210
a1=00001000 a1=00001004
address $1000 now contains 76543210
6. ADDRESS REGISTER INDIRECT ADDRESSING WITH PRE-DECREMENT
Assembler syntax: -(An) (n between 0 and 7)
This addressing mode resembles the address register indirect
addressing mode. The only difference is that after before
fetching or storing the data, the address register is decre
mented. The decrement depends on the suffix used in the opcode.
If the suffix is .b then the address register will be decremented
by one. If the suffix is .w then the address register will be
decremented by two (one word is two bytes). If the suffix is .l
then the address register will be decremented by four (one
longword is four bytes). In assembler this addressing mode is
denotated by putting the address register within parentheses
preceded by a - sign. For example: -(a7)
E.g.:
Instruction Before After
MOVE.L -(A1),D0 d0=ffffffff d0=01234567
a1=00001004 a1=00001000
address $1000 contains 01234567
MOVE.W -(A1),D0 d0=ffffffff d0=ffff4567
a1=00001004 a1=00001002
address $1000 contains 01234567
MOVE.B -(A1),D0 d0=ffffffff d0=ffffff67
a1=00001004 a1=00001003
address $1000 contains 01234567
MOVE.L D0,-(A1) d0=76543210 d0=76543210
a1=00001004 a1=00001000
address $1000 now contains 76543210
7. ADDRESS REGISTER INDIRECT ADDRESSING WITH DISPLACEMENT
Assembler syntax: w(An) (w stands for word displacement)
This addressing is also rather similar to address register
indirect addressing. The only difference lies in the fact that
before fetching or moving the data a 16-bit signed displacement
is added to the contents of the address register (the address
register itself does not change). In assembler this addressing
mode is denotated by enclosing the address register name in
parentheses preceded by a 16-bit constant. For example: 8(a6)
denotes the memory location whose address is the contents of a6
plus 8. This addressing method comes in very handy when passing
parameters to subroutines.
By the way, did you ever wonder why the ATARI ST has a resolution
of 640 by 400 pixels?
Here's one reason: 640*400=256000 bits=32000 bytes. Since 32000
bytes can be addressed using 16 bits, the address register
indirect with displacement is an easy way to address the screen.
E.g.:
Instruction Before After
MOVE.L 8(A1),D0 d0=ffffffff d0=01234567
a1=00001000 a1=00001000
address $1008 contains 01234567
MOVE.L D0,-6(A1) d0=76543210 d0=76543210
a1=00001006 a1=00001006
address $1000 now contains 76543210
8. ADDRESS REGISTER INDIRECT ADDRESSING WITH INDEX
Assembler syntax: b(An,Rn.w) or b(An,Rn.l)
( b stands for byte, w and l for word and longword and R for
register).
This addressing mode makes it possible to add a variable index
(contained in an address or data register) to an address register
and also an eight bit signed displacement. The variable index
may be either word or longword. Both the index and displacement
are sign extended before they are added to the address register.
E.g.:
Instruction Before After
MOVE.L 8(A1,A0.L),D0 d0=ffffffff d0=01234567
a1=00001000 a1=00001000
a0=00078000 a0=00078000
address $79008 contains 01234567
MOVE.L 8(A1,A0.W),D0 d0=ffffffff d0=01234567
a1=00001000 a1=00001000
a0=00078000 a0=00078000
*** a0.w=8000 -> sign-extend gives ffff8000 ***
address $ffff8008 contains 01234567
MOVE.W 8(A1,D0.L),D0 d0=0001fffe d0=00010123
a1=00001000 a1=00001000
*** 00001000 (contents of a1)
0001fffe (contents of d0.l)
00000008 (sign-extended byte displacement)
---------
00021006
address $21006 contains 01234567
MOVE.L 8(A1,D0.W),D0 d0=0001fffe d0=01234567
a1=00001000 a1=00001000
*** 00001000 (contents of a1)
fffffffe (sign-extended contents of d0.w)
00000008 (sign-extended byte displacement)
---------
00001006
address $1006 contains 01234567
9. ABSOLUTE SHORT ADDRESSING
Assembler syntax: x (x is a 16 bit constant)
With absolute short addressing it is only possible to specify a
16 bit constant. At execution time the 68000 sign extends the
word into a long address, meaning that only addresses 0 to 7fff
and ffff8000 to ffffffff can be addressed using this form. This
addressing mode can be compared with zero-page addressing on the
6502 and direct-page addressing on the 6809.Like on the 6502 and
6809 this mode is faster than any other mode. This addressing
mode can be compared with zero-page addressing on the 6502 and
direct-page addressing on the 6809.
By the way, on the Atari ST, the lower 32 K of memory can only be
accessed in supervisor-mode (the S-bit in SR is set, see part I).
E.g.:
Instruction Before After
MOVE.L $1234,D0 d0=ffffffff d0=01234567
address 1234 contains 01234567
( the $ sign is used to denote a hex digit)
MOVE.L $8000,D0 d0=ffffffff d0=76543210
address $ffff8000 contains 76543210
10. ABSOLUTE LONG ADDRESSING
Assembler syntax: l (l is 32 bit constant)
With this addressing mode a long address is supplied. It is very
similar to absolute short addressing.
E.g.:
Instruction Before After
MOVE.L $12345678,D0 d0=ffffffff d0=01234567
address $00345678 contains 01234567
Note that since the address bus is only 24 bits wide the upper
byte of the address is ignored by the 68000.
11. PROGRAM COUNTER WITH DISPLACEMENT
Assembler syntax: x(PC) (x is a 16 bit constant)
This addressing mode is in fact the same as address register
indirect with displacement. The only difference is that the
address register is replaced with the PC (the PC is in fact also
an address register).
E.g.:
Instruction Before After
MOVE.L 8(PC),D0 d0=ffffffff d0=01234567
pc=00001000 pc=00001000
address $1008 contains 01234567
12. PROGRAM COUNTER WITH INDEX
Assembler syntax: b(PC,Rn.L) or b(PC,Rn.w) (b is 8 bits)
This mode is in fact the same address register indirect
addressing with index.
E.g.:
Instruction Before After
MOVE.L 8(PC,A0.L),D0 d0=ffffffff d0=01234567
pc=00001000 pc=00001000
a0=00078000 a0=00078000
address $79008 contains 01234567
MOVE.L 8(PC,A0.W),D0 d0=ffffffff d0=01234567
pc=00001000 pc=00001000
a0=00078000 a0=00078000
*** a0.w=8000 -> sign-extend gives ffff8000 ***
address $ffff8008 contains 01234567
MOVE.W 8(PC,D0.L),D0 d0=0001fffe d0=00010123
pc=00001000 pc=00001000
*** 00001000 (contents of pc)
0001fffe (contents of d0.l)
00000008 (sign-extended byte displacement)
---------
00021006
address $21006 contains 01234567
MOVE.L 8(PC,D0.W),D0 d0=0001fffe d0=01234567
pc=00001000 pc=00001000
*** 00001000 (contents of pc)
fffffffe (sign-extended contents of d0.w)
00000008 (sign-extended byte displacement)
---------
00001006
address $1006 contains 01234567
13. IMMEDIATE ADDRESSING
Assembler syntax: #x (x is byte, word or longword)
The data for the operation is the value x. Programmers of the
6502 and 6809 will recognize this addressing mode. For example
(6502 and 6809) LDA #$21.
E.g.:
Instruction Before After
MOVE.L #$A03B4C11,D0 d0=00000000 d0=a03b4c11
14. STATUS REGISTER ADDRESSING
Assembler syntax: SR or CCR
This mode is used to control the contents of this register. See
part I of this course for the individual meanings of the bits
contained in this register. Changes to the SR can only be made
when in user-mode. Changes to the CCR can be made in any mode.
E.g.:
Instruction Before After
MOVE.W SR,D0 d0=87654321 d0=87652700
sr=2700 sr=2700
MOVE.W #$0500,SR sr=2700 sr=0500
Notice that the 68000 was in supervisor mode before executing the
instruction but after completion it is in user mode!! This
operation isn't possible the other way around.
To conclude this part, I will give you a summary of the
addressing modes of the 68000.
SYNTAX NAME
-----------------------------------
Dn | Data register direct
An | Address register direct
(An) | Address register indirect
(An)+ | Address register indirect with post-increment
-(An) | Address register indirect with pre-decrement
w(An) | Address register with displacement
b(An,Rn) | Address register with index
w | Absolute short
l | Absolute long
w(PC) | PC with displacement
b(PC,Rn) | PC with index
#x | Immediate
SR or CCR | Status register
b is a byte constant
w is a word constant
l is a long constant
x any of b, l or w
n is a register number ranging from 0 to 7
R is a register specifier, either A or D
If you have any comments on these courses, please let me know!
Disclaimer
The text of the articles is identical to the originals like they appeared
in old ST NEWS issues. Please take into consideration that the author(s)
was (were) a lot younger and less responsible back then. So bad jokes,
bad English, youthful arrogance, insults, bravura, over-crediting and
tastelessness should be taken with at least a grain of salt. Any contact
and/or payment information, as well as deadlines/release dates of any
kind should be regarded as outdated. Due to the fact that these pages are
not actually contained in an Atari executable here, references to scroll
texts, featured demo screens and hidden articles may also be irrelevant.