我正在尝试在汇编中解决这些简单的乘法和除法运算。
5*4 + 35/7
我已经完成了这个
mov al,5
mov bl,4
mul bl
mov ax,35
mov bl,7
div bl
AX 寄存器中我之前的乘法值会被除法的新结果覆盖。我该如何解决这个问题?
答案 0 :(得分:2)
Emu8086基于8086指令,因此您只有 MUL 和 DIV 的单操作数版本。只是为了让您知道,IMUL是MUL的签名版本,IDIV是DIV的签名版本。假设您打算执行无符号算术,您的代码可能如下所示:
mov al,5
mov bl,4
mul bl
mov cx, ax ; Save AX to CX
mov ax,35
mov bl,7
div bl
xor ah, ah ; Result(quotient) of DIV in AL, ensure AH is zero
add ax, cx ; AX=AX+CX
使用 MUL 和 DIV 的8086特定指令无法阻止 AX 被破坏。您必须将值移动到临时区域。我们将在上面的代码中使用寄存器 CX 。由于我们将 MUL 指令的结果保存到 CX ,我们只需要将它添加到 DIV 指令的结果中(其中商是在 AL )。我们将存储在 AH 中的余数归零,将商保留在 AL 中。 AX 现在包含我们添加到 CX 的商(作为16位值),并且等式的最终结果存储在 AX
乘以4的简化是将值左移2位。这段代码:
mov al,5
mov bl,4
mul bl
mov cx, ax ; Save AX to CX
可以简化为:
mov cx, 5
shl cx, 2 ; Multiply CX by 4
除了通过 CL 寄存器之外,8086处理器不支持 SHL 移位超过1位。 EMU8086的汇编程序会自动将SHL reg, imm
指令转换为一个或多个SHL, reg, 1
指令。在这种情况下,SHL CX, 2
被翻译为:
shl cx, 1 ; Multiply CX by 2
shl cx, 1 ; Multiply CX by 2 again
大多数8086汇编程序不会为您执行此翻译。或者,可以在 CL 寄存器中指定要移位的位数。这个(或等效的)适用于大多数8086汇编程序:
mov cl, 2 ; Number of bits to shift left by in CL
mov dx, 5
shl dx, cl ; Shift DX to the left by CL(2) is equivalent to multiply by 4
mov ax,35
mov bl,7
div bl
xor ah, ah ; Result(quotient) of DIV in AL, ensure AH is zero
add ax, dx ; AX=AX+DX
答案 1 :(得分:2)
我之前在AX寄存器中乘法的值会被除法的新结果覆盖。我该如何解决这个问题?
足够简单。将乘法的结果放在一个额外的寄存器中(我使用DX
),计算表达式的下一个项,最后添加两个结果。重要的是要注意AL
寄存器中的商仅,因此在添加之前需要清除AH
寄存器! (示例中使用的数字" 35/7"在AH
中产生0的余数但是当你被要求编写程序时你不应该依赖它!)
mov al,5
mov bl,4
mul bl ; -> Result is in AX
mov dx, ax
mov ax,35
mov bl,7
div bl ; -> Result is in AL
mov ah, 0
add ax, dx ; -> Final result is in AX
答案 2 :(得分:1)
您需要乘以5 * 4然后将值推入堆栈。然后进行第二次计算,划分。然后弹出堆栈的第一个值并将值一起添加。
答案 3 :(得分:1)
回答主要问题:您可以使用imul reg, reg, imm
将其乘法放入不同的寄存器中。或者您可以mov ecx, eax
将结果保存在div
不需要的注册表中。
由于您没有说明数据的来源,显而易见的事情是在汇编时执行计算。
mov eax, 5*4 + 35/7
如果您仍想在运行时计算,则需要从立即数,寄存器或内存中的值开始。在这里说明这些的混合很方便(因为div
没有立即操作数形式)
通常最好使用默认操作数大小,即32位和64位模式下的32位。但是,8位操作通常不会慢。
mov eax, 35
div byte [seven] ; al = ax/7, ah=ax%7. wider operand sizes divide edx:eax by the src.
mov cl, 5
lea eax, [ecx*4 + eax] ; al = cl*4 + al. Ignore the garbage in the high bits.
; result in al
section .rodata
seven: db 7
div
很慢,所以compilers replace divides by constants with multiplies by funky constants, and shift the result,因为这可能是2的补码溢出。
请参阅Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?,了解使用lea
乘以4并添加,而不清除高位。