1

我试图在汇编中制作一个简单的计算器。我使用了 TASM(学校政策)。问题是在 DT 变量中打印使用 FBSTP 命令(协处理器命令)保存的数字。

FBSTP adr - 将位于堆栈顶部的值 (ST (0)) 存储在地址“adr”中作为压缩十进制数(在“adr”中定义为 DT)。堆栈指针递减。转换是在存储过程中完成的。

我调试了程序,当除以 10 时,结果被破坏了。例如:12*1=12。res2 中的结果是正确的。将它移动到 AX 后它仍然是正确的,但是当我将它除以 10 时,DX 变为 8 而不是 2,所以它打印出 18 而不是 12。我还注意到 12h=18d 但我无法建立连接。LE:如果我在 word 变量中使用一个简单的整数存储并打印它,它就可以正常工作。

这是我认为重要的代码部分:

multiplication:
FINIT
FILD x
FILD y
FMUL
FBSTP res2
FWAIT
MOV ax,WORD PTR res2
call write
jmp_line
jmp exit  


write       PROC    NEAR ;my printing proc moves cursor x spaces and starts writing
                          from back to front

    PUSH    DX
            PUSH    AX
    PUSH    CX
    MOV     CX,0

    CMP     AX, 0;check sign
    JNS     ok_write
    NEG     AX ;negate if <0
    MOV     CX,1 ;used to know if number is negative


ok_write:
    printspace ;macro that jumps 5 spaces(maximum number length)
    ;starts printing the number backwards
    print_digit:
    inc len
    ;print each digit
    MOV DX,0 ;prepare DX for storing the remeinder
    DIV CS:ten ;divide AX by 10 so that the last digit of the number is stored
    ADD dl,30h ;transform to ascii
    PUSH AX ;save AX
    MOV ah,02h
    INT 21h  ;print last digit
    printchar   8 ;put cursor over last printed digit
    printchar   8 ;move cursor in front of last printed digit

    cmp divi,1  ;
    JNE not_div
    cmp len,1
    JNE not_div
    printchar '.'
    printchar   8
    printchar   8

    not_div:
    POP AX ;retreive AX
    CMP AX,0 ;when AX=0 the number is written
    JNE print_digit
    ;/print each digit
    CMP     CX,1
    JNE     end_print
    printchar   '-'
   end_print:

    POP     CX
    POP     AX
    POP     DX
    RET
  write       ENDP  

非常感谢。

4

1 回答 1

0

您在 AX 中加载一个 BCD 数字。BCD 表示二进制编码的十进制。所以每个 4 位实际上是一个十进制值。你除以 10,也是十进制。但是 AX 将数字视为十六进制。如果您尝试将 12 (bcd) 除以 10(十进制),则 12 将被视为十六进制,十进制值为 18。 18 除以 10(十进制)或 0Ah 最终得到十进制的 18。如果 12 是 bcd,您只需将压缩 bcd(每 4 位是十六进制编码的十进制)转换为未压缩(每 8 位代表一个十进制数字)。让事情变得更容易:如果 AX 包含 12(bcd) 那么你可以和 AX 用 0Fh 把 2 取出来,用 0F0h 把 1 取出来。对于数字,您只需添加 30h(“0”)即可。对于帐篷,您将 4 位剪掉并添加 30h(“0”)。再次:如果将 AX = 12 中的压缩 bcd 转换为 AX = 0102 中的未压缩 BCD 并添加 3030h,则 AX 将包含 12(bcd) 的 ASCII。要将其存储在屏幕上打印,您必须知道低 8 位将存储在内存的低地址中。因此 AH 和 AL 与 xchg AH 交换,AL 因此 AX = 3231h 并存储在 DS 中的内存位置。对于大于 99(bcd) 的数字,您应该使用相同的技术来提取数百、数千等......我希望这能解决问题。

于 2015-02-16T11:34:16.537 回答