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