1

アセンブリで簡単な電卓を作ってみました。私はTASM(学校の方針)を使いました。問題は、FBSTP コマンド (コプロセッサ コマンド) で保存された数値を DT 変数に出力することです。

FBSTP adr - パックド 10 進数 (DT で「adr」に定義) としてスタック (ST (0)) の一番上にある値をアドレス「adr」に格納します。スタック ポインタがデクリメントされます。変換はストア プロセス中に行われます。

プログラムをデバッグしましたが、10 で割ると結果が壊れます。例: 12*1=12。res2 の結果は正しいです。AX に移動した後も正しいですが、10 で割ると DX は 2 ではなく 8 になるため、12 ではなく 18 が出力されます。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 とは、2 進化 10 進数を意味します。したがって、各 4 ビットは実際には 10 進数値です。10 で割ります。これも 10 進数です。ただし、AX は数値を 16 進数として扱います。12 (bcd) を 10 (10 進数) で除算しようとすると、12 は 16 進数として扱われ、10 進数の値は 18 になります。12 が bcd の場合、パックされた bcd (各 4 ビットは 16 進数でコード化された 10 進数) からアンパック (各 8 ビットは 10 進数を表す) に変換するだけで済みます。物事を簡単にするために: AX に 12(bcd) が含まれている場合、AX に 0Fh を指定して 2 を取得し、AX に 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 に答える