2012-02-05 61 views
1

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

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

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

这里是代码的一部分,我认为计数:

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 

非常感谢。

+0

我还没有分析您发布的整个代码,但有一件奇怪的事情是:'DIV CS:ten'。如果'ten'在数据段中并且'CS'与'DS'不一样,那么您可能会被除了'ten'之外的东西分开。尝试除以预先加载10的寄存器,例如'mov si,10' +'div si'。 – 2012-03-30 10:10:10

回答

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,AX用0F0h来得到1。 对于数字,您只需向其中添加30h(“0”)即可。对于帐篷,您可以放置​​4位,并向其添加30小时(“0”)。 再次说明:如果您将AX = 12中的打包bcd转换为AX = 0102中的解包BCD并将3030h添加到AX中,则AX将包含12(bcd)的ASCII。 要存储此信息以便将其打印在屏幕上,您必须知道低8位将存储在内存中的较低地址中。 因此,将AH和AL与xchg AH,AL进行交换,因此AX = 3231h并存储在DS中的存储位置。 对于大于99(bcd)的数字,你应该使用相同的技术来提取数百,数千等......我希望这将清除一切。