在68000汇编程序

时间:2016-01-02 18:33:45

标签: 68000

有人可以帮我解决这个68000汇编程序吗?  创建一个程序,将两个长字v1和v3无符号相乘。产品是64位的数字。值v1 qnd和v2分别位于数据寄存器D1和D2上?  谢谢你的回答,对不起我的坏英语

3 个答案:

答案 0 :(得分:3)

只要将无符号32位数相乘,就可以使用以下方法: 理论:如果您的32位数量是A和B,则将它们拆分为: A = Ah * 0x10000 + Al,B = Bh * 0x10000 + B1,其中Ah,Al,Bh,B1各自为0到0xFFFF。

然后,显然,

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

这4个乘法中的每一个都是16位* 16位 - > 32位,因此非常适合68000 mulu.w命令。

所以代码:

    ;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

当然,这段代码有很多优化的可能性。

答案 1 :(得分:1)

您遇到的问题是MUL只有16位,这意味着如果您有64位结果,则需要按4个16位多次和加法的顺序进行。然后将结果返回两个寄存器,因为每个寄存器都是32位。

假设您想要A x B,并且A是AH和AL,B是BH和BL 您将获得一系列部分产品:

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

4个部分产品中的每一个都积累在64位字的各自部分中,为了使事情更有趣,你需要考虑这些部分。

我将呈现的内容与寄存器的内容有所不同,但如果您能理解,您可以根据自己的需要进行更改。假设A6是堆栈,我们将在D0中返回高32位字的结果,D1用于低32位字。这是我的库中的一段代码

$ a=b
$ b=lol
$ echo ${!a}
lol

答案 2 :(得分:1)

这是由Amiga Aztec C编译器生成的代码,用于乘以两个32位整数:

D0 / D1:输入 D0:输出

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