我正在使用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
;我被困在这里...
答案 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值如何用于编码不同的值,例如整数,浮点数,字符串等。常见的“类型”和信息是什么编码。