2012-02-05 60 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)的數字,你應該使用相同的技術來提取數百,數千等......我希望這將清除一切。