如何在汇编中显示11.1之后的div?

时间:2011-02-12 14:09:48

标签: assembly x86 x86-16

如何在div之后显示11.1?例如,32/5 = 6.4,我只能显示6,那么如何显示6.4?

OUT23:

    MOV BL,CNT  ;CNT is the total number of even number
    DIV BL
    MOV DL,AL
    MOV BH,AL
    MOV AH,09H
    LEA DX,MSG23
    INT 21H
    MOV DL,BH   ;print out the average, only the integer part able to display
    MOV AH,02
    ADD DL,30H
    INT 21H

3 个答案:

答案 0 :(得分:2)

DIV是一个整数除法指令。如果您想要浮点除法,那么您需要查看FDIV

答案 1 :(得分:2)

如前所述,DIV执行整数除法。由于它是整数除法,因此得到的商和余数在单独的寄存器对中可用,确切的寄存器取决于除数的大小。

1 Byte Divisor

AX - Dividend
AH - Remainder
AL - Quotient

2 Byte Divisor

DX:AX - Dividend
DX - Remainder
AX - Quotient

4字节除数

EDX:EAX - Dividend
EDX - Remainder
EAX - Quotient

由于使用1字节除数'BL',余数将在AH寄存器中。在您32/5的情况下,AL寄存器将包含值6AH注册值2,这意味着剩余的2/5 } 0.4为您提供6.4的答案。

如果您决定使用FPU操作,则需要使用32指令将两个值5FLD加载到FPU堆栈,每个值一次,之后调用FDIV将弹出FPU堆栈中的两个值,将它们分开并将结果推送到FPU堆栈。

然后可以使用FSTP指令将结果从堆栈移到存储器地址。获得结果后,您需要将其从二进制IEEE浮点表示转换为可以在屏幕上显示的字符串表示。

答案 2 :(得分:2)

如果你想除以两个整数并打印小数结果,那么就像在小学时手动划分一样。初始除法将给出结果的整数部分,然后将剩余部分重复乘以10并除以除数直到它为零或已达到预期的精度以得到分数

以上面的32/5为例

  • 整数部分:

    32/5 = 6 → Print out "6."
    
  • 分数部分:

    Remainder: 2, multiply it by 10 → 2*10 = 20
    20/5 = 4 → Print out "4"
    Remainder: 0, stop here
    

可以像上面那样进行更复杂的划分,只需在每一步之后将余数乘以10即可。如果结果是无限的,那么当你获得足够的精度时就停止。

另一个例子:25/11 = 2.27272727 ......

  25/11 = 2 R 3 → 2.
3*10/11 = 2 R 8 → 2
8*10/11 = 7 R 3 → 7
3*10/11 = 2 R 8 → 2
8*10/11 = 7 R 3 → 7
and so on...

如果使用浮点值并使用FDIV进行浮点除法,那么有很多方法可以将浮点数转换为字符串,但是要获得正确的舍入结果非常困难,所以最好只使用库来制作为此目的。

然而,对于非常简单的演示,那么也可以使用上述方法:

  • 拆分结果的整数部分并打印后跟.
  • 将整数部分乘以10,整数部分将是下一个小数位
  • 删除整数部分并重复上述步骤,直至达到所需的精度

一个粗略的例子是这样的,忽略了由二进制浮点属性引起的错误

11.157
Int part: 11    → print 11.
Fractional part:
0.157*10 = 1.57 → print 1
 0.57*10 = 5.7  → print 5
  0.7*10 = 7    → print 7

更详细的信息可以在Turn float into string

中找到