gpt4 book ai didi

assembly - 在 8086 微处理器上将 32 位两个数字相乘

转载 作者:行者123 更新时间:2023-12-02 22:15:38 27 4
gpt4 key购买 nike

我有在 8086 上将两个 16 位数字相乘的代码示例,并尝试更新它以实现两个 32 位数字相乘。

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 位数字相乘。

要将其更新为 32 位两个数字,我知道我需要如下更新:

  1. AX 更改为 00000002h,将 BX 更改为 00000008h
  2. 再使用两个寄存器(我不知道应该使用哪个寄存器)来保存第二个和第三个16位乘法(因为乘法将是64位。16位乘法4次。我目前有DX和CX。)
  3. 将循环编号更新为 20h(在这种情况下为 SI)(对于 32 位数字来说是 32 次)

8086 是 16 位微处理器,因此它的寄存器也是。我无法为寄存器分配 32 位长的数字。

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注册吗?

提前致谢。

最佳答案

授人以鱼,然后等等……

很好,你有一个代码示例。但你了解算法吗?

好吧,让我们通过一个简化的例子一步一步地看一下:将 ALAH 中的两个 8 位寄存器相乘,并将结果存储在 中DX.

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

但在我们真正开始之前,您提供的算法有一些优化。你知道, assembly 就是优化。无论是为了速度还是为了尺寸。否则你会用 C# 或其他方式编写臃肿软件。否则。

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

这部分的作用只是检查AX中的第一位(位#0)是否已设置。你可以简单地做

TEST AX, 1
JNZ ADD

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

下一步,

RCR DX,1

不需要轮换,因此可以简单地为SHR DX, 1。但两条指令的执行时间相同,而且都是两个字节长,因此在本例中并不重要。

下一步,

DEC SI
CMP SI,0
JNZ LOOP

永远不要在 DEC 之后与零进行比较。是莫顿!简单地做

DEC SI
JNZ LOOP

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

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

应该是

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

这里我们对您进行了一些优化的例程:

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 位寄存器。

 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:

这是一个Long Multiplication algorithm

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

添加 34 小时平移两次:

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

就是这样!现在要使用更多数字,您可以使用相同的方法。下面是 fasm 语法的实现。结果存储在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

干杯;)

关于assembly - 在 8086 微处理器上将 32 位两个数字相乘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29246857/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com