两个16位寄存器相乘后如何从DX:AX中提取内容以进行进一步计算? 8086汇编代码

时间:2018-08-01 16:20:20

标签: assembly x86-16

我正在使用DOSBOX 0.74编写8086汇编代码

我计划将两个2字节的数字相乘以产生一个非常大的数字。 3333 X 999 = 3,329,667

该值将存储在DX:AX中。我的问题是如何求出乘积并存储到单个存储器或寄存器中,因此我可以执行其他算术运算,例如对该值进行除法。

我做了一些研究。我见过有人建议使用push和pop,但我不确定它是否被使用。

我的代码如下:

num1 db 3333
num2 db 999
mov ax, num1
mov bx, num2
mul bx

;我被困在这里...

2 个答案:

答案 0 :(得分:2)

Ped7g 答案的重要部分,如果您希望结果为内存中的 dd var 0 双字:

mov word ptr [var], ax
mov word ptr [var+2], dx

值将合并到变量 var

答案 1 :(得分:0)

  

如何从DX:AX中提取内容...

好吧,内容就在其中,您无需以任何方式提取它。如果您要乘以较小的值,则结果只适合16位,例如123 * 45 = 5535,则在dx = 0, ax = 5535之后插入mul

在您的示例中(固定num1/num2后,您正在执行3333 * 999 = 3329667,该格式为二进制:0000_0000_0011_0010_1100_1110_1000_0011,这32位就像存储在dx:ax中的位,即{{ 1}}和dx = 0000_0000_0011_0010 = 0032h = 50。 (和50 * 2 16 + 52867 = 3329667)。

没有什么可以“提取”的,它已经是32位整数,可以用于进一步的计算了。


对代码进行修复,并附上注释以试图解释我所显示的内容:

ax = 1100_1110_1000_0011 = 0CE83h = 52867

data: num1 dw 3333 ; fixed to "dw" to define word (16b) num2 dw 999 mulResult dd 0 ; reserve 32 bits of memory code: mov ax, [num1] mov bx, [num2] mul bx ; dx:ax = ax * bx ; store 32 bits into memory (in little-endian way) mov [mulResult],ax mov [mulResult+2],dx ; now you can load it back into 32b register on 80386+ CPUs: mov eax,[mulResult] ; or if you are on 8086-80286 CPU, you can load it back into dx:ax pair ; by loading the 16 bit parts separately mov ax,[mulResult] mov dx,[mulResult+2] mov bx,10000 div bx ; ax = dx:ax / bx (quotient), dx = remainder dx是16位寄存器。它们在mul之后设置,以包含32位结果的高16位和低16位。

您不能将其存储到单个(16b)寄存器或单个字存储器中(不适合)。您必须将所有32位存储在某个地方。

您的来源也可以使用ax,但是num1 db 3333不适合字节(需要至少12位以简单的“无符号整数”编码进行编码),因此在组装后您可以值3333而不是地址5处的地址num1

然后3333将加载两个字节,而不是一个...

请注意计算机中信息的编码方式,二进制的0/1值如何用于编码不同的值,例如整数,浮点数,字符串等。常见的“类型”和信息是什么编码。