Форум программистов, компьютерный форум, киберфорум
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/230: Рейтинг темы: голосов - 230, средняя оценка - 4.90
Программист
307 / 182 / 176
Регистрация: 05.12.2013
Сообщений: 683
Записей в блоге: 5
1
TASM

Простейший калькулятор

03.06.2012, 03:14. Показов 45441. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Стоит задача следующего типа: написать простейший калькулятор, умеющий выполнять действия сложения и вычитания и контролировать переполнение. Проблема возникла в следующем моменте - при вычитании двух различных чисел (разных знаков, и одинаковых в том числе) рассчет и вывод верный, а при суммировании операндов с различными знаками, происходит неверный подсчет. Прошу помощи

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
.model small
.stack 100h
 
data segment      
   _errorCF db 'Finded overflow at ADD operation!','$'  
   _errorOF db 'Finded overflow at SUB operation!','$'             
   _INFO    db 'Types of operations:',10,13,'1. + -> sum',10,13,'2. - -> subtraction',10,13,'$'           
   _nc      db 10,13,'$'
   first    dw 65535    ;первый операнд
   second   dw 5         ;второй операнд
data ends
   
code segment
assume cs:code,ds:data     
begin:
        mov ax,data         
        mov ds,ax           
        mov es,ax           ;es ссылается туда же, где и ds
;------------------------------------------------
;Вывод приглашения на ввод числа
        mov ah,09h          ;команда на вывод строки
        mov dx,offset _INFO ;смещение на строку
        int 21h             ;выполнить команду
;------------------------------------------------
;Определяем тип операции
enter_type_operation: 
        mov ah,01h            ;вызов команды ввода символа с клавиатуры
        int 21h               ;выполнить команду
        cmp al,'+'            ;введен "+" 
        je summ               ;да -> суммируем 2 числа
        cmp al,'-'            ;введен "-" 
        je minus              ;да -> вычитаем 2 числа
        jmp enter_type_operation;во всех других случаях - повтор ввода
;------------------------------------------------
;Суммирование двух чисел
summ:
        mov ah,09h            ;команда на вывод строки
        mov dx,offset _nc     ;в dx смещение на строку
        int 21h               ;выполнить команду
        mov ax,first          ;ax=first
        mov bx,second
        add ax,bx             ;ax=ax+bx
        jnc write_res         ;если нет переноса(CF=0), то вывод результата
        jmp errorCF           ;иначе вывести ошибку
;------------------------------------------------
minus:
        mov ah,09h            ;команда на вывод строки
        mov dx,offset _nc     ;в dx смещение на строку
        int 21h               ;выполнить команду
        mov ax,first          ;ax=first 
        mov bx,second
        sub ax,bx             ;ax=ax-bx
        jno write_res         ;если нет заема(OF=0), то вывод результата
        jmp errorOF           ;иначе вывести ошибку
;------------------------------------------------
;Вывод числа
write_res:
        test ax,ax            ;проверим знак числа
        jns init              ;SF=0? если да, то просто вывод числа
        mov cx,ax             ;иначе выводим как отрицательное, cx=ax
        mov ah,02h            ;выводим символ
        mov dl,'-'            ;поместим в dl символ минуса
        int 21h               ;выполним команду
        mov ax,cx             ;вернем старое значение, cx=ax
        neg ax                ;сменим знак операнда     
init:
        xor cx,cx             ;cx=0
        xor dx,dx             ;dx=0
    push -1               ;сохраним признак конца числа
    mov cx,10         ;делим на 10
repeat: 
        xor dx,dx         ;очистим регистр dx
    div cx                ;делим 
    push dx               ;сохраним цифру
    cmp ax,0          ;остался 0? (оптимальнее or ax,ax)
    jne repeat        ;нет -> продолжим
    mov ah,2h             ;вывод символа
digit:  
        pop dx                ;восстановим цифру
    cmp dx,-1         ;дошли до конца -> выход {оптимальнее: or dx,dx jl ex}
    je exit               ;завершить вывод
    add dl,'0'        ;преобразуем число в цифру
    int 21h               ;выведем цифру на экран
    jmp digit         ;и продолжим 
;------------------------------------------------
;Вывод ошибки о переполнении, при операции сложения
errorCF:
        mov ah,09h            ;команда на вывод строки
        mov dx,offset _errorCF;в dx смещение на строку
        int 21h               ;выполнить команду
        jmp exit              ;переход по метке
;------------------------------------------------
;Вывод ошибки о заеме, при операции вычитания       
errorOF:
        mov ah,09h            ;команда на вывод строки
        mov dx,offset _errorOF;в dx смещение на строку
        int 21h               ;выполнить команду
        jmp exit              ;переход по метке
;------------------------------------------------ 
exit:
        mov ax,4c00h       
        int 21h
code ends
end begin
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.06.2012, 03:14
Ответы с готовыми решениями:

Написать простейший дизассемблер
Привет Кто нибудь писал дизассемблер(наипростейший)?? С чего начать?Какие книги посоветуете?...

Простейший планировщик процессов
Всем привет. Нам в лабораторной работе дали задание: Написать на ассемблере IBM PC программу...

Простейший планировщик процессов
Помогите пожалуйста написать программу! В ассемблере разбираюсь плоховато, буду рад любым...

Простейший калькулятор
Калькулятор считает сумму, разность, произведение и частное двух чисел a и b Код: #include...

8
273 / 268 / 11
Регистрация: 24.12.2010
Сообщений: 328
03.06.2012, 10:55 2
В 43 строке должно быть jno вместо jnc.
0
Программист
307 / 182 / 176
Регистрация: 05.12.2013
Сообщений: 683
Записей в блоге: 5
03.06.2012, 11:07 3
Цитата Сообщение от Ant1971on Посмотреть сообщение
В 43 строке должно быть jno вместо jnc.
Но разве при операции сложения не CF флаг учитывается, а не OF, как для вычитания? Хотя я попробовал - но проблемы это не решило.
В целом суть какая:
При сложении получается, что на входных данных, скажем первый операнд 65532, а второй 5, то получается что при сложении получим переполнение, что верно. В то время, как при вычитании получим -9, что впринципе не верно.
0
273 / 268 / 11
Регистрация: 24.12.2010
Сообщений: 328
03.06.2012, 11:43 4
Лучший ответ Сообщение было отмечено как решение

Решение

Операнды должны быть в диапазоне от -32768 до 32767 для знаковых чисел типа word. Число 65532 в качестве операнда годится только при операциях с числами без знака.
3
Программист
307 / 182 / 176
Регистрация: 05.12.2013
Сообщений: 683
Записей в блоге: 5
03.06.2012, 11:49 5
Цитата Сообщение от Ant1971on Посмотреть сообщение
Операнды должны быть в диапазоне от -32768 до 32767 для знаковых чисел типа word. Число 65532 в качестве операнда годится только при операциях с числами без знака.
Спасибо. Сейчас попробовал так:

а)
первый операнд 32767
второй операнд -5
результат: при вычитании и разности получил переполнения
б)
первый операнд 32767
второй операнд 5
результат: при сумме получил -32764(верно?), при разности 32762(это верно)
Так должно все получится? Верно?
0
202 / 168 / 11
Регистрация: 30.05.2012
Сообщений: 703
03.06.2012, 11:59 6
Цитата Сообщение от Arigato Посмотреть сообщение
первый операнд 32767
второй операнд -5
результат: при вычитании и разности получил переполнения
Смотри:
-5 = 65531

32767-65531 будет заем.



Цитата Сообщение от Arigato Посмотреть сообщение
первый операнд 32767
второй операнд 5
результат: при сумме получил -32764(верно?), при разности 32762(это верно)
Так должно все получится? Верно?
Сумма не верная, потому что
32767+5 = 32772
32772 имеет единичный знаковый бит, поэтому считается отрицательным числом.
Не задавай предельные значения!
2
273 / 268 / 11
Регистрация: 24.12.2010
Сообщений: 328
03.06.2012, 12:02 7
a) 32767-(-5)=32772 -> переполнение -> выход.
б) 32767+5=32772 -> тоже, 32767-5=32762 -> верно.
2
Программист
307 / 182 / 176
Регистрация: 05.12.2013
Сообщений: 683
Записей в блоге: 5
03.06.2012, 12:04 8
Цитата Сообщение от Anonimys Посмотреть сообщение
Смотри:
-5 = 65531
32767-65531 будет заем.

Сумма не верная, потому что
32767+5 = 32772
32772 имеет единичный знаковый бит, поэтому считается отрицательным числом.
Не задавай предельные значения!
Спасибо. Просто я решил проверять именно калькулятор на граничных значениях.
На значениях -15 и 5 получил -10 и -20 соответственно.
На значениях -15 и -5 получил -10(разность) и -20(при сумме,что верно)
0
0 / 0 / 0
Регистрация: 13.09.2016
Сообщений: 13
04.06.2023, 10:12 9
Это простейший калькулятор на masm32_fenix.zip
0
04.06.2023, 10:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.06.2023, 10:12
Помогаю со студенческими работами здесь

Простейший калькулятор
Помогите пож переделать немного код. По заданию нужно чтобы мы вводили 2 числа в поля 1 и 2. И...

Простейший калькулятор
Не нашел ни одного хорошего кода калькулятора для новичков. Чтобы они поняли как устроены...

Простейший калькулятор
Доброго времени суток! Только начал изучать Java. До этого с программированием не сталкивался,...

Простейший калькулятор
Есть код на решение примеров +,-,*. при запуске знаков или не видно или они не правильно стоят.(((...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru