Search code examples
assemblyeasy68k

Easy68k. How can i use the index correctly in a loop?


ORG $400400
COUNT   DC.B 4
NUM1    DC.B $4E,$57,$29,$5A,$3B  
NUM2    DC.B $31,$D4,$55,$E0,$9B


       ORG $400410
SUBRTN MOVE.B $400401,D0
   LEA $400405,A0
   LEA $400410,A1
LOOP
   ADDX -(A0),-(A1)
   DBRA D0,LOOP
      END $400410 

So i have this code, and i want use an index (A0) at the end of of my nums1 (offset $400405),and an index (A1) at the end of my nums 2 (offset $400410), i want to create a loop that adds the indexes (ADDX -(A0),-(A1)) and store the add result to the end of my nums2 in descending order ($400405,$400404,$400403 etc.)

Also i think that i need to use DBRA for my 5 loops but im kinda stuck cause i lack experiance on programming on the 68k

Note: Running this code gives me the error "Address Error: Instruction at 400422 accessing address 400403"


Solution

  • I believe that ADDX without a qualifier is doing ADDX.L (or ADDX.W).  Try writing ADDX.B instead.

    It is possible that ADDX.B won't be accepted by the assembler, as various online texts seem to disagree as to whether ADDX.B exists.  (There appears to be an encoding for it in the machine code, though.)

    The address $400403 comes because the processor is pre-decrementing A0, which holds $400405, by 2 bytes to access a 16-bit word (possibly as part of the 2 word accesses necessary on the 16-bit bus to fetch a longword).  Odd addresses cannot be used with 16-bit data or 32-bit data in (most if not all of) the MC68k family of processors, hence the exception.

    From http://www.tigernt.com/onlineDoc/68000.pdf :

    The ADDX instruction is used in chain arithmetic to add together strings of bytes (words or longwords). Consider the addition of two 128-bit numbers, each of which is stored as four consecutive longwords.

        LEA Number1,A0 A0 points at first number
        LEA Number2,A1 A1 points at second number
        MOVEQ #3,D0 Four longwords to add
        MOVE #$00,CCR Clear X-bit and Z-bit of the CCR
    LOOP
        ADDX -(A0),-(A1) Add pair of numbers
        DBRA D0,LOOP Repeat until all added
    

    Let's make some observations:

    1. Unadorned ADDX is being used to perform 32-bit arithmetic.

    2. DBRA D0, LOOP decrements 16-bit register d0.w — but you are loading a byte into d0.b, meaning the upper 8 bits of d0.w are technically undefined (though the simulator may have started all the registers as initially zero).  The moveq instruction they are using initializes the full 32-bit register, d0.l.

    3. You are loading the value $4E into d0.b (instead of 4) because you have an off by 1 error in the address.

    4. The above sample uses move #$00, CCR to positively clear the X-bit before the start of the loop that uses extended arithmetic via ADDX.