在8086微处理器上乘以32位两个数字 [英] Multiplying 32 bit two numbers on 8086 microprocessor
问题描述
我有一个代码示例,将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:
- 将
AX
更改为00000002h
,将BX
更改为00000008h
. - 再使用两个寄存器(我不知道应该使用哪个寄存器)来保存第二个和第三个16位乘法(因为乘法将是64位.16位持续4次.我目前拥有DX和CX.)
- 将循环号更新为
20h
(在这种情况下为SI
)(对于32位数字,这是32次)
- Change
AX
to00000002h
andBX
to00000008h
. - 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.)
- 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
我的问题是:
- 如何为一个32位数字处理两个不同的寄存器. (寄存器是16位的,所以我必须将数字分成两个寄存器)
- 我可以为此目的使用哪些寄存器?我可以随意使用 any 注册吗?
- 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)
- 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?
好吧,让我们逐步讲一个简化的示例:将两个AL
和AH
中的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屋!