The 68000 has 14 different ways to address things in the memory. This example will use the instruction MOVE (LD on Z80, MOV on x86) to demonstrate how they work. Later, in the instruction summary, you'll see that when an instruction has <ea> (effective address) as an argument, it doesn't mean it can use all 14 ways to address. It almost always has restrictions.
DATA REGISTER DIRECT
Syntax: Dn (where n is 0-7)
Example: MOVE.L D1,D0 copies the contents of D1 to D0. When the instruction is executed, both registers will contain the same information. When moving a byte or a word, the upper part of the register will remain unchanged.
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
ADDRESS REGISTER DIRECT
Syntax: An (n is 0-7)
Example: MOVE.L A1,D0 copies all of A1 to D0. After the instruction, both registers contain the same information. When transferring address registers, you must use word or longword. When a word is transferred TO an address register, bit 15 (the sign bit) will be copied trough the whole upper word (bit 16-31). If it wasn't so, a negative number would become positive.
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 | |
MOVE.W D0,A1 | D0=0000FFFF | D0=0000FFFF |
A1=00000000 | A1=FFFFFFFF |
ADDRESS REGISTER INDIRECT
Syntax: (An) (n is 0-7)
Example: MOVE.L (A0),D0 copies the longword stored at address location A0 (you say A0 points to the longword). If you refer to a word or a longword, the address in the address register must be an even number. THIS CAN CAUSE BIG PROBLEMS AND UNEXPECTED ERRORS!
Instruction | Before | After |
MOVE.L (A1),D0 | D0=FFFFFFFF | D0=01234567 |
A1=00001000 | A1=00001000 | |
$1000=01234567 | $1000=01234567 |
ADDRESS REGISTER INDIRECT WITH POST-INCREMENT
Syntax: (An)+ (n is 0-7)
Description.: Works the same as the previous addressing mode, except that after the instruction, register An will be increased with the size of the operation. A special case is when you use A7 and transfer a byte, because A7 will be increased with 2 instead of 1, because A7, as the stack pointer, must be an even number.
Example: MOVE.L (A1)+,D0 copies the longword which A1 points to to D0, and increases A1 by 4 bytes.
Instruction | Before | After |
MOVE.L (A1)+,D0 | D0=FFFFFFFF | D0=01234567 |
A1=00001000 | A1=00001004 | |
$1000=01234567 | $1000=01234567 |
ADDRESS REGISTER INDIRECT WITH PRE-DECREMENT
Syntax: -(An) (n is 0-7)
Description.: Works the same as the previous addressing mode, except that register An will first be decreased with the operand size (with the exception of A7), then the data will be transferred. Example: MOVE.L -(A1),D0 first decreases A1 by 4 bytes, then copies the longword stored at A1 to D0.
Instruction | Before | After |
MOVE.L -(A1),D0 | D0=FFFFFFFF | D0=01234567 |
A1=00001004 | A1=00001000 | |
$1000=01234567 | $1000=01234567 |
ADDRESS REGISTER INDIRECT WITH DISPLACEMENT
Syntax: x(An) (x is 16 bit, n is 0-7)
Description: The location pointed at x+An is the one that will be copied.
Example: MOVE.L 4(A1),D0 copies the longword stored at A1+4 to D0. A1 will, after the instruction, remain unchanged. Note that if x is bigger than $7FFF, it means a negative value. It's because of the sign extension.
Instruction | Before | After |
MOVE.L 4(A1),D0 | D0=FFFFFFFF | D0=01234567 |
A1=00001000 | A1=00001000 | |
$1004=01234567 | $1004=01234567 |
ADDRESS REGISTER INDIRECT WITH INDEX
Syntax: x(An,Dn.L) (x is an 8 bit signed constant, n is 0-7)
x(An,Dn.W)
x(An,An.W)
x(An,An.L)
Description.: Works the same as the previous addressing mode, except that another register also will be added (if it's a word, a sign extension will be made before, so it will be a subtraction). When working with words or longwords, the generated address must be an even address.
Example: MOVE.L 4(A1,A2.L),D0 copies the longword stored at A1+A2+4 to D0. A1 and A2 will after the instruction remain unchanged. Note that if x is bigger than $7F, it means a negative value. It's because of the sign extension.
Instruction | Before | After |
MOVE.L 4(A1,A2.L),D0 | D0=FFFFFFFF | D0=01234567 |
A1=00001000 | A1=00001000 | |
A2=00001000 | A2=00001000 | |
$2004=01234567 | $2004=01234567 |
ABSOLUTE SHORT ADDRESS
Syntax: x (x is a 16 bit signed constant)
Description: The address will be sign extended before it's used, but the MSB is ignored (don't bother about that). The sign extension means that near addressing can only be used on the first 32Kb.
Example: MOVE.L $1000,D0 copies the longword stored at $1000 to D0. Note that there is no parentheses! If you mean an immediate value, you put a # before the value (see below). However, adding the parentheses is not a bad idea: the assembler will accept it and it will add in readability to the source.
Instruction | Before | After |
MOVE.L $1000,D0 | D0=FFFFFFFF | D0=01234567 |
$1000=01234567 | $1000=01234567 |
Forcing Absolute Short Addressing: In EASy68K if an instruction such as: MOVE.L $8000,D0 is assembled the assembler will automatically use absolute long addressing and encode the address as $00008000. It is possible to force the assembler to use absolute short addressing by using .W as: MOVE.L $8000.W,D0. Forcing short addressing will always result in a Warning message "Forcing SHORT addressing disables range checking of extension word".
Instruction | Before | After |
MOVE.L $8000,D0 | D0=FFFFFFFF | D0=01234567 |
$00008000=01234567 | $00008000=01234567 | |
MOVE.L $8000.W,D0 | D0=FFFFFFFF | D0=87654321 |
$00FF8000=87654321 | $00FF8000=87654321 |
ABSOLUTE LONG ADDRESS
Syntax: x (x is a 32 bit constant)
Description: Works EXACTLY as the last one, except that x is a 32 bit value (the instruction is two bytes longer also).
Example: MOVE.L $10000,D0 copies the longword stored at $10000 to D0.
Instruction | Before | After |
MOVE.L $10000,D0 | D0=FFFFFFFF | D0=01234567 |
$10000=01234567 | $10000=01234567 |
Forcing Absolute Long Addressing: In EASy68K if an instruction such as: MOVE.L $1000,D0 is assembled the assembler will automatically use absolute short addressing and encode the address as $1000. It is possible to force the assembler to use absolute long addressing by using .L as: MOVE.L $1000.L,D0.
Instruction | Code |
MOVE.L $1000,D0 | 2038 1000 |
MOVE.L $1000.L,D0 | 2039 00001000 |
PROGRAM COUNTER WITH DISPLACEMENT
Syntax: x(PC) or (x,PC) (x is a 16 bit signed constant)
Description: The displacement word (x) is specified as an
address relative to the current PC. The assembler calculates the relative
offset to the displacement address and adds the resulting number to the
program counter to determine the address. The displacement is a signed
number (meaning that the limits are -32768 to +32767). This addressing mode
may be used to write programs that are position independent. Position
independent programs and their local data may be moved to any area of memory
and will run correctly. This is possible if all references to local data are
made with PC relative addressing.
Example: MOVE.L $1102(PC),D0 copies the longword stored at
PC+$102 to D0 assuming the current PC is $1000.
Instruction | Before | After |
MOVE.L $1102(PC),D0
assuming PC=$1000 |
D0=FFFFFFFF | D0=01234567 |
$1102=01234567 | $1102=01234567 |
PROGRAM COUNTER WITH INDEX
Syntax: x(PC,Dn.L) or (x,PC,Dn.L) (x is an 8 bit signed constant, n is 0-7)
x(PC,Dn.W) or (x,PC,Dn.W)
x(PC,An.W) or (x,PC,An.W)
x(PC,An.L) or (x,PC,An.L)
Description: The displacement byte (x) is specified as an
address relative to the current PC. The assembler calculates the relative
offset to the displacement address and adds the resulting number the program
counter and the sign extended index register to determine the address. The
displacement is a signed number (meaning that the limits are -128 to +127).
This addressing mode may be used to write programs that are position
independent. Position independent programs and their local data may be moved
to any area of memory and will run correctly. This is possible if all
references to local data are made with PC relative addressing.
Example: MOVE.L $1010(PC,A1.L),D0 copies the longword stored at
PC+A1+$10 to D0 assuming the current PC is $1000.
Instruction | Before | After |
MOVE.L $1010(PC,A1.L),D0
assuming PC=$1000 |
D0=FFFFFFFF | D0=01234567 |
$2010=01234567 | $2010=01234567 | |
A1=00001000 | A1=00001000 |
IMMEDIATE DATA
Syntax: #x (x is 8, 16 or 32 bits)
Description: Uses the immediate value x.
Example: MOVE.L #$10002000,D0 copies $10002000 to D0. Note that if you copy a word to an address register, the word will be sign extended.
Instruction | Before | After |
MOVE.L #$10002000,D0 | D0=01234567 | D0=10002000 |
ADDRESSING WITH THE STATUS REGISTER
Syntax: SR
CCR
Description: The only instructions that are allowed to use this address mode are: ANDI (AND immediate), EORI (exclusive OR immediate), and ORI (OR immediate). If the length is a byte, the flag register is changed. If it's a word, both the flag register and the system byte are changed (but only if the supervisor bit is set) The assembler recognize both SR (that means both flags and system-byte) and CCR (only flag register), so you don't have to specify the length.
Example: The instruction ORI #5,CCR sets both the carry flag (C) and the zero flag (Z). The other flags remains unchanged.
Note: #5=#%00000101
Instruction | Before | After |
ORI #5,CCR | CCR=0000 | CCR=0005 |