-1

can anyone help me on this exercice on 68000 assembler please? create a program that multiply two long words v1 and v3 unsigned. the product is number on 64 bits. the values v1 qnd v2 are respectively on the data registers D1 and D2 ? thanks for your answers and sorry for my bad english

3 Answers3

3

As long as you multiply unsigned 32-bit quantities, you can use the following way: Theory: if your 32-bit quantities are A and B, split them like this: A=Ah*0x10000+Al, B=Bh*0x10000+Bl, where each of Ah,Al,Bh,Bl is from 0 to 0xFFFF.

Then, obviously,

A * B = Ah * Bh<<32 + Al * Bh<<16 + Ah * Bl<<16 + Al * Bl

Each of these 4 multiplies is 16bit*16bit->32bit, thus perfectly fitting 68000 mulu.w command.

So the code:

    ;unsigned d0.l * d1.l -> d2.l:d3.l (d2.l holds high part)

    move.w  d0,d3
    mulu.w  d1,d3 ;d3.l is Al*Bl now

    swap    d0
    swap    d1
    move.w  d0,d2
    mulu.w  d1,d2 ;d2.l is Ah*Bh now

    swap    d0
    move.w  d0,d4
    mulu.w  d1,d4 ;d4 is Al*Bh

    swap    d4
    moveq   #0,d5
    move.w  d4,d5
    clr.w   d4      ; d5:d4 is 0x0000:Nh:Nl:0x0000, where N is Al*Bh

    add.l   d4,d3
    addx.l  d5,d2   ;add Al*Bh*0x10000 to the partial result in d2:d3

    swap    d0
    swap    d1

    move.w  d0,d4
    mulu.w  d1,d4 ;d4 is Ah*Bl

    swap    d4
    moveq   #0,d5
    move.w  d4,d5
    clr.w   d4      ; d5:d4 is 0x0000:Nh:Nl:0x0000, where N is Ah*Bl

    add.l   d4,d3
    addx.l  d5,d2   ;add Ah*Bl*0x10000 to the partial result

    ;d2:d3 is now the result

Of course, this code has many possibilities for optimization.

lvd
  • 793
  • 3
  • 12
1

You have the problem that the MUL is only 16-bit, which means that if you have a 64-bit result, you need to do it in a sequence of 4 16-bit multiples and additions. You then return the result in two registers, as each register is 32-bits.

Assume you want A x B, and that A is AH and AL, with B as BH and BL You get a series of partial products:

1: BL x AL
2: BL x AH x 2^16
3: BH x 2^16 x AL
4: BH x 2^16 x AH x 2^16

Each of the 4 partial products accumulate in their own section of the 64-bit word, and to make matters more interesting, you need to consider the carries.

What I will present is different from what you need as far as registers, but if you can understand it, you can change it for your exercise. Assume that A6 is the stack, and we’ll return the result in D0 for the high 32-bit word, and D1 for the low 32-bit word. Here’s a snippet of code from my library

umul32: link        a6, #0
        movem.l     d2-d4, -(sp)
        move.l      (multiB,a6), d4 ;B into d4
        move.l      (multiA,a6), d3 ;A into d3
        moveq       #0,d2
        moveq       #0,d1
        moveq       #0,d0
mshift1:    lsr.l       #1,d4           ; look for 1 in multiplier
        bcc.s       mshift2     ; branch on 0
        add.l       d3,d1           ; add shifted A to product
        addx.l      d2,d0           ; add carry if found
mshift2:    lsl.l       #1,d3           ; shift for next iteration
        roxl.l      #1,d2
        tst.l       d4          ; check for 1s
        bne.s       mshift1
        movem.l     (sp)+,d2-d4
        ulnk        a6
        move.l      (sp),(8,sp)     ;clean the 8 entries off the stack
        addq.l      8, sp
        rts
b degnan
  • 672
  • 1
  • 14
  • 31
1

This is code generated by Amiga Aztec C compiler for multiplying two 32 bits integers :

D0/D1 : input D0 : output

move.w  d1,d2
mulu    d0,d2
move.l  d1,d3
swap    d3
mulu    d0,d3
swap    d3
clr.w   d3
add.l   d3,d2
swap    d0
mulu    d1,d0
swap    d0
clr.w   d0
add.l   d2,d0
rts
sebastien
  • 11
  • 1