在8086微处理器上乘以32位两个数字 [英] Multiplying 32 bit two numbers on 8086 microprocessor

查看:130
本文介绍了在8086微处理器上乘以32位两个数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个代码示例,将8086上的两个16位数字相乘,并尝试将其乘以两个32位数字相乘.

I have code example for multiplying two 16 bit numbers on 8086 and trying to update it for two 32 bit numbers multiplying.

start:
 MOV AX,0002h ; 16 bit multiplicand
 MOV BX,0008h ; 16 bit multiplier
 MOV DX,0000h ; high 16 bits of multiplication
 MOV CX,0000h ; low 16 bits of multiplication
 MOV SI,10h ; loop for 16 times

LOOP:
 MOV DI,AX
 AND DI,01h
 XOR DI,01h
 JZ ADD
CONT:
 RCR DX,1
 RCR CX,1
 SHR AX,1
 DEC SI
 CMP SI,0
 JNZ LOOP
 JMP END ; ignore here, it's not about multiplication. 
ADD:
 ADD DX,BX
 JMP CONT

上面的代码语句将两个16位数字相乘.

Code statements above multiply two 16 bit numbers.

要将其更新为32位两个数字,我知道我需要像这样的更新:

To update it for 32 bit two numbers, I know I need updates like:

  1. AX更改为00000002h,将BX更改为00000008h.
  2. 再使用两个寄存器(我不知道应该使用哪个寄存器)来保存第二个和第三个16位乘法(因为乘法将是64位.16位持续4次.我目前拥有DX和CX.)
  3. 将循环号更新为20h(在这种情况下为SI)(对于32位数字,这是32次)
  1. Change AX to 00000002h and BX to 00000008h.
  2. Use two more registers (I don't know which registers I should use) to hold second and third 16 bits of multiplication (because multiplication will be 64 bit. 16 bit for 4 times. I currently have DX and CX.)
  3. Update loop number to 20h(SI in that case) (that makes 32 times for 32 bit number)

8086是16位微处理器,因此其寄存器也是如此.我不能为寄存器分配32位长的数字.

8086 is 16-bit microprocessor so its registers are. I can't assign registers 32-bit-long numbers.

8086的寄存器:

REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
SREG: DS, ES, SS, and only as second operand: CS.

来源: http://www.electronics.dit.ie/staff/tscarff/8086_instruction_set/8086_instruction_set.html

我的问题是:

  1. 如何为一个32位数字处理两个不同的寄存器. (寄存器是16位的,所以我必须将数字分成两个寄存器)
  2. 我可以为此目的使用哪些寄存器?我可以随意使用 any 注册吗?
  1. How can I handle two different registers for one 32-bit number. (registers are 16-bit, so I have to split the number into two registers)
  2. What registers can I use for that purpose? Am I free to use any register arbitrarily?

谢谢.

推荐答案

给男人一条鱼,等等等等……

Give a man a fish and blah-blah-blah…

这很好,您有一个代码示例.但是您了解算法吗?

It’s good, that you have a code example. But do you understand the algorithm?

好吧,让我们逐步讲一个简化的示例:将两个ALAH中的8位寄存器相乘,并将结果存储在DX中.

Okay, let’s go through it step by step on a simplified example: multiplying two 8-bit registers in AL and AH, and storing the result in DX.

顺便说一句,您可以使用任何您喜欢的寄存器,除非该指令或该指令需要任何特定的寄存器.例如,SHL reg, CL.

BTW, you can use any registers you like unless this or that instruction requires any particular register. Like, for example, SHL reg, CL.

但是,在我们真正开始之前,对您提供的算法进行了一些优化.组装就是最优化.无论是速度还是尺寸.否则,您会使用C#或smth来做膨胀软件.其他.

But before we actually start, there’re a couple of optimizations for the algorithm you provided. Assembly is all about optimization, you know. Either for speed or for size. Otherwize you do bloatware in C# or smth. else.

MOV DI,AX
AND DI,01h
XOR DI,01h
JZ ADD

这部分的作用是简单地检查AX中的第一位(位0)是否被置位. 你可以简单地做

What this part does is simply checks if the first bit (bit #0) in AX is set or not. You could simply do

TEST AX, 1
JNZ ADD

但是您只需要测试一位,因此TEST AL, 1而不是TEST AX, 1可以为您节省一个字节.

But you only need to test one bit, thus TEST AL, 1 instead of TEST AX, 1 saves you one byte.

下一步

RCR DX,1

无需轮换,因此只需将其替换为SHR DX, 1.但是两条指令都需要花费相同的时间来执行,而且两个字节都长,因此在此示例中无关紧要.

There’s no need in rotation, so it could simply be SHR DX, 1. But both instructions take the same time to execute and both two bytes long, thus doesn’t matter in this example.

下一步

DEC SI
CMP SI,0
JNZ LOOP

DEC之后再也不能与零进行比较.是莫文顿!只需

Never ever compare with zero after DEC. It’s moveton! Simply do

DEC SI
JNZ LOOP

接下来, 不必要的循环拆分

Next, Unnecessary loop split

JZ ADD
CONT:
. . .
JMP END
ADD:
ADD DX, BX
JMP CONT
END:
. . .

应该是

JNZ CONT
ADD DX, BX
CONT:
. . .
END:
. . .

在这里,我们为您提供了一些经过优化的例程:

Here we go with a bit optimized routine you have:

LOOP:
 TEST AL, 1
 JZ SHORT CONT
 ADD DX, BX
CONT:
 RCR DX, 1
 RCR CX, 1
 SHR AX, 1
 DEC SI
 JNZ LOOP
END:

就是这样.现在返回(或前进?)这小段代码的实际作用.以下代码示例完全模仿您的示例,但使用8位寄存器.

That’s it. Now back (or forward?) to what this little piece of code actually does. The following code sample fully mimics your example, but for 8-bit registers.

 MOV AL,12h   ; 8 bit multiplicand
 MOV AH,34h   ; 8 bit multiplier
 XOR DX, DX   ; result
 MOV CX, 8    ; loop for 8 times

LOOP:
 TEST AL, 1
 JZ SHORT CONT
 ADD DH, AH
CONT:
 SHR DX, 1
 SHR AL, 1
 DEC CX
 JNZ LOOP
END:

这是长乘法算法

 12h = 00010010
               x
 34h = 01110100
       --------
       00000000
      01110100
     00000000
    00000000
   01110100
  00000000
 00000000
00000000

两次相移34h:

0000000011101000
+
0000011101000000
----------------
0000011110101000 = 03A8

就是这样! 现在,要使用更多数字,您可以使用相同的方法.下面是fasm语法的实现.结果存储在DX:CX:BX:AX

That’s it! Now to use more digits you use the same approach. Below is the implementation in fasm syntax. Result is stored in DX:CX:BX:AX

Num1    dd 0x12345678
Num2    dd 0x9abcdef0

 mov si, word [Num1]
 mov di, word [Num1 + 2]
 xor ax, ax
 xor bx, bx
 xor cx, cx
 xor dx, dx
 mov bp, 32

_loop:
 test si, 1
 jz short _cont
 add cx, word [Num2]
 adc dx, word [Num2 + 2]
_cont:
 rcr dx, 1
 rcr cx, 1
 rcr bx, 1
 rcr ax, 1
 rcr di, 1
 rcr si, 1
 dec bp
 jnz short _loop

干杯;)

这篇关于在8086微处理器上乘以32位两个数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆