# Effective Addressing

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.

1. 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

3. 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

4. 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

5. 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

6. 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

7. 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

8. 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

9. 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

10. 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

11. 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

12. 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

13. 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

14. 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