2012-02-05 5 views
1

Я попытался сделать простой калькулятор в сборке. Я использовал TASM (школьная политика). Проблема заключается в печати номера, сохраненного командой FBSTP (команда сопроцессора) в переменной DT.Печать упакованного BCD (DT) - язык ассемблера (TASM)

FBSTP адр - магазины по адресу «адр» значения, расположенного на верхней части стека (ST (0)) в виде упакованного десятичного числа (определены в „адр“ с DT). Указатель стека уменьшается. Конверсия выполняется во время процесса хранения.

Я отлаживал программу, и при делении на 10 результат был поврежден. Например: 12 * 1 = 12. Результат в res2 правильный. Переместив его в AX, все еще правильно, но когда я делю его на 10 DX, становится 8 вместо 2, поэтому вместо 12 он выводит 18. Я также заметил , что 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' находится в сегменте данных, а' CS' - это не то же самое, что 'DS', вы можете делиться чем-то другим, чем' десять'. Попробуйте делить на регистр, предварительно загруженный с 10, например. 'mov si, 10' +' div si'. –

ответ

0

Вы загружаете номер BCD в AX. 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»). Опять же: если вы конвертируете упакованный bcd в AX = 12 в распакованный BCD в AX = 0102 и добавьте к нему 3030h, AX будет содержать ASCII 12 (bcd). Чтобы сохранить это для печати на экране, вы должны знать, что младшие 8 бит будут храниться в нижних адресах в памяти. Поэтому swith AH и AL с xchg AH, AL, таким образом, AX = 3231h и сохраняются в памяти в DS. Для чисел, которые больше 99 (bcd), вы должны использовать ту же технику для извлечения сотен, тысяч и т. Д. ... Надеюсь, что это прояснит ситуацию.