Калькулятор. Некорректное деление.

Тема в разделе "WASM.BEGINNERS", создана пользователем hiss, 12 янв 2007.

  1. hiss

    hiss New Member

    Публикаций:
    0
    Регистрация:
    12 янв 2007
    Сообщения:
    2
    Пишу калькулятор.

    Входные данные: дисятичное числа из двух цифр.
    Выходные: результат арифм. действия.

    Для умножения нужно писать "*" между цифрами. Для деления - "/". А для сложения и вычитания - "+" и "-" соответсвенно.

    Пример:
    Vvedite: 12 + 12
    Rezultat: 24

    Код (Text):
    1. data segment    
    2.     s1  db  '',13,10,'Vvedite primer:$'
    3.         s2      db      ' $'
    4.         s3      db      '',13,10,'Oshibka. Vvedite povtorno.$'
    5.         s4      db      '',13,10,'Rezultat: $'
    6.     x       dw      10
    7.     b       dw      0
    8.     c       dw      0
    9. data ends
    10. stk segment stack
    11.     dd  128 dup (0)
    12. stk ends
    13. text segment 'code'
    14.         assume cs:text,ds:data
    15.  
    16. vvod    proc
    17.         mov ah,9h
    18.     mov dx,offset s2
    19.     int 21h
    20.  
    21.         mov     b,0
    22.         mov     cl,2h
    23.  
    24. m1: mov     ah,1h
    25.     int     21h
    26.         call    prov
    27.  
    28.         sub     al,30h
    29.  
    30.     cbw
    31.     mov     si,ax
    32.     mov     ax,b
    33.     mul     x
    34.     add     ax,si
    35.     mov     b,ax
    36.     loop    m1
    37.        
    38.         ret
    39. endp
    40.  
    41. vivod   proc
    42.         mov ah,9h
    43.     mov dx,offset s4
    44.     int 21h
    45.         mov     ax,c
    46.         mov     cl,0h
    47. M2:     xor     dx,dx
    48.     div     x
    49.     push    dx
    50.         inc     cx
    51.     cmp     ax,0
    52.     jne     m2
    53.  
    54. M3: pop     dx
    55.     add     dl,30h
    56.     mov     ah,2h
    57.     int     21h
    58.     loop    m3
    59.         call    vihod
    60. endp
    61.  
    62. prov    proc
    63.         cmp al,39h
    64.     jg  osh
    65.     cmp     al,30h
    66.     jl  osh
    67.        
    68.         ret
    69.  
    70. osh:    mov ah,9h
    71.     mov     dx,offset s3
    72.     int     21h
    73.         call    main
    74. endp
    75.  
    76. prov2   proc
    77.         cmp al,2ah
    78.     je  m4
    79.     cmp     al,2fh
    80.     je  m5
    81.         cmp al,2bh
    82.     je  m6
    83.     cmp     al,2dh
    84.     je  m7
    85.        
    86.         jmp     osh2
    87.  
    88. M4:     call    umn
    89.  
    90. m5:     call    del
    91.  
    92. M6:     call    slozh
    93.  
    94. m7:     call    vich
    95.  
    96. osh2:   mov ah,9h
    97.     mov     dx,offset s3
    98.     int     21h
    99.         call    main
    100. endp
    101.  
    102. umn     proc
    103.         xor     dx,dx
    104.         mov     dx,b
    105.         mov     c,dx
    106.         call    vvod
    107.         mul     c
    108.         mov     c,ax
    109.         call    vivod
    110. endp
    111.  
    112. del     proc
    113.         xor     dx,dx
    114.         mov     dx,b
    115.         mov     c,dx
    116.         call    vvod
    117.         div     c
    118.         mov     c,ax
    119.         call    vivod
    120. endp
    121.  
    122. slozh   proc
    123.         xor     dx,dx
    124.         mov     dx,b
    125.         mov     c,dx
    126.         call    vvod
    127.         add     c,ax
    128.         call    vivod
    129. endp
    130.  
    131. vich    proc
    132.         xor     dx,dx
    133.         mov     dx,b
    134.         mov     c,dx
    135.         call    vvod
    136.         sub     c,ax
    137.         call    vivod
    138. endp
    139.  
    140. vihod   proc
    141.         mov ah,1h
    142.         int     21h
    143.         mov     ah,4ch
    144.         int 21h
    145. endp
    146.        
    147. main    proc   
    148.     mov ax,data
    149.     mov ds,ax  
    150.     xor ax,ax
    151.         mov     cx,0
    152.        
    153.         mov ah,9h
    154.     mov     dx,offset s1
    155.     int     21h
    156.  
    157.         call    vvod
    158.  
    159.         mov ah,9h
    160.     mov dx,offset s2
    161.     int 21h
    162.  
    163.         mov     ah,1h
    164.     int     21h
    165.         call    prov2
    166.  
    167.         mov ah,9h
    168.     mov     dx,offset s1
    169.     int     21h
    170. main endp
    171. text ends      
    172. end main
    Прошу обратить особое внимание на процедуру ДЕЛЕНИЯ. Видимо что-то с ней не так, поскольку оно (это самое деление) выполняется неправильно.
    Код (Text):
    1. del     proc
    2.         xor     dx,dx
    3.         mov     dx,b
    4.         mov     c,dx
    5.         call    vvod
    6.         div     c
    7.         mov     c,ax
    8.         call    vivod
    9. endp
     
  2. hiss

    hiss New Member

    Публикаций:
    0
    Регистрация:
    12 янв 2007
    Сообщения:
    2
    Ах да, забыл. Компилирую Tasm'ом. Версия 2.54, по-момеу.
     
  3. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Код (Text):
    1.         xor     dx,dx
    2.         mov     dx,b
    3.         mov     c,dx
    4.         call    vvod
    5.         div     c
    Команда div делит ax:dx на значение регистра, или области памяти. Соответственно, в твоем случае (деление, как я понял, беззнаковое) dx перед командой div надо обнулить. И не совсем понятно, зачем обнулять dx до передачи b в c. + такая обработка ошибок (фактически рекурсия) не есть хорошо: если наошибаться много -- стек накроется.
     
  4. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.351
    делит ax на значение. Результат помещает в ax, остаток - в dx
     
  5. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Нет, не только ax. В зависимости от размера операнда ah:al, dx:ax, edx:eax, rdx:rax. В приведенном примере (word) будет dx:ax.