Консультация № 193474
16.08.2018, 11:42
0.00 руб.
16.08.2018, 11:54
0 12 0
Здравствуйте! Прошу помощи в следующем вопросе:
Арифмометр для целых положительных чисел. С конвертацией, вроде-бы, разобрался, но результаты
работы арифмометра - не радуют: к результату сложения-вычитания добавляется "0", а к результату
умножения - "00".
Арифмометр здесь: fenix.asm, data.inc, const.inc

Обсуждение

давно
Посетитель
401688
22
16.08.2018, 11:44
общий
16.08.2018, 11:49
Адресаты:
Вроде-бы - создал.
В ссылке опечатка: нужно "cupoma58.ru/assembler_04.html,.."
давно
Посетитель
7438
7205
16.08.2018, 11:50
общий
Адресаты:
Отлично
Повторю, что сказал ранее:
Цитата: Лысков Игорь Витальевич
У Вас неправильно работает функция asc2bin, а именно, сначала умножается на 10, затем проверяется очередной символ на 0, а должно быть наоборот
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Старший Модератор
31795
6196
16.08.2018, 13:56
общий
Адресаты:
Повторю И.В.
Цитата: Лысков Игорь Витальевич
У Вас неправильно работает функция asc2bin, а именно, сначала умножается на 10, затем проверяется очередной символ на 0, а должно быть наоборот



И добавлю совсем не правильно.
[code lang=asm]asc2bin proc ;(((eax*10)+edx)*10+edx)*...
pushad
. . .
cycl:
. . .
inc esi ;к следующему символу
jc exit ;если CF=1
jmp cycl ;повторим
fin:
. . .
popad
exit: ;для возможной обработки CF
ret
asc2bin endp[/code]
Тут две ошибки:
1) Если будете ждать пока ESI переполнится, то раньше ОСЬ сама выбросит критическую ошибку, т.к. Вы залезете командой mov dl,[ esi ], в системную область старших адресов.
2) Даже если ОСь пропустит это событие и ESI таки переполнится, то выход из п/пр-ммы будет происходить по значению одного из регистров РОН(они все ещё в стеке) .

Теперь алгоритм перевода ascii -> bin:
Есть всего 8-мь РОН:EAX,EBX,ECX,EDX,ESI,EDI EBP,ESP
Начинаем определятся с используемыми регистрами:
EAX, EBX, ECX, EDX, ESI, EDI, [s]EBP, ESP[/s] - использоваь нельзя, они используются системой и п/пр-ммой;
[s]EAX[/s], EBX, ECX, [s]EDX[/s], ESI, EDI, [s]EBP, ESP[/s] - использовать нельзя, т.к. используются в командах MUL и DIV;
[s]EAX[/s], EBX, ECX, [s]EDX[/s], ESI, EDI, [s]EBP, ESP[/s] - ВЫ используете как указатель строки;
[s]EAX[/s], EBX, ECX, [s]EDX[/s], ESI, EDI, [s]EBP, ESP[/s] Вы используете как основание системы счисления.
Остались ЕВХ и ЕСХ, я использовал ЕВХ:
[code lang=asm]asc2bin proc ;(((eax*10)+edx)*10+edx)*...
pushad
xor edx,edx ;обнулимся...
xor eax,eax
mov edi,10 ;10 - основание системы счисления
lea esi,buf ;адрес 1-го ASCII-символа
cycl:
mov bl,[esi] ;выберем ASCII-символ
or bl,bl ;нечего выбирать?
jz fin ;на выход

mul edi ;edx:eax = eax*10
and bl,0Fh ;преобразуем ASCII-символ
movzx ebx,bl ;расширяем
add eax,ebx ;промежуточная сумма
inc esi ;к следующему символу
;
or edx,edx
jz cycl
stc
;
; jc exit ;если CF=1
; jmp cycl ;повторим
fin:
mov bin,eax ;сохраним дв.число
popad
; exit: ;для возможной обработки CF
ret
asc2bin endp[/code]
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
7438
7205
20.08.2018, 11:51
общий
Адресаты:
Ну что там с программой? Разобрались? Еще есть вопросы?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401688
22
22.08.2018, 15:09
общий
Адресаты:
Здравствуйте. Благодарю за подсказку. С регистрами я разберусь. Просто - работаю по книжным примерам. А вопросы, по программе, остались. Я изменил порядок проверки очередного символа в процедуре asc2bin, как вы посоветовали. В работе арифмометра это ничего не изменило: к сумме и к разности по прежнему добавляется "0" --> 2+3=50, 8-6=20. А к произведению - сразу "00" --> 7*9=6300. С делением - всё в порядке. Подозреваю конвертацию, а в чём дело - не понимаю.
давно
Посетитель
7438
7205
22.08.2018, 15:16
общий
Адресаты:
Я же говорил:
Цитата: Лысков Игорь Витальевич
У Вас неправильно работает функция asc2bin, а именно, сначала умножается на 10, затем проверяется очередной символ на 0, а должно быть наоборот
В результате происходит лишнее умножение на 10. Покажите код функции asc2bin.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401688
22
22.08.2018, 15:18
общий
22.08.2018, 15:35
Адресаты:
cupoma58.ru/assembler_04.html
Код:

asc2bin proc ;(((eax*10)+edx)*10+edx)*...
pushad
xor edx,edx ;обнулимся...
xor eax,eax
mov edi,10 ;10 - основание системы счисления
lea esi,buf ;адрес 1-го ASCII-символа
cycl:
mov dl,[esi] ;выберем ASCII-символ <-- bl
or dl,dl ;закончились символы?
jz fin ;завершаем преобразование
mul edi ;edx:eax = eax*10
and dl,0Fh ;преобразуем ASCII-символ
movzx dx,dl ;расширяем...
movzx edx,dx ;...расширяем
add eax,edx ;промежуточная сумма
inc esi ;к следующему символу <-- ecx
jc exit ;если CF=1
jmp cycl ;повторим
fin:
mov bin,eax ;сохраним дв.число
popad
exit: ;для возможной обработки CF
ret
asc2bin endp
давно
Посетитель
7438
7205
22.08.2018, 15:58
общий
Адресаты:
Ну так, ничего ж не сделали... Вам же К.Н. предложил сделать так: [code lang=asm]asc2bin proc ;(((eax*10)+ebx)*10+ebx)*...
pushad
xor ebx,ebx ;обнулимся...
xor eax,eax
mov edi,ten ;10 - основание системы счисления
lea esi,buf ;адрес 1-го ASCII-символа
cycl:
mov bl, [esi] ;выберем ASCII-символ
inc esi
or bl,bl ;нечего выбирать?
jz fin ;на выход (кроме того С будет равен 0)
mul edi ;edx:eax = eax*10
and bl,0Fh ;преобразуем ASCII-символ
add eax,ebx ;промежуточная сумма
or edx,edx ;проверка на переполнение DWORD-а
jz cycl
stc
fin:
mov bin,eax ;сохраним дв.число
popad
ret
asc2bin endp
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401688
22
22.08.2018, 16:13
общий
Адресаты:
Почему EDX ? Он, вроде-бы, нигде не фигурирует:
Цитата: Лысков Игорь Витальевич
or edx,edx ;проверка на переполнение DWORD-а

Ещё раз - благодарю за подсказку. Буду пробовать, дома. Я в интернет выхожу из читального зала городской библиотеки, когда он там есть.
давно
Посетитель
7438
7205
22.08.2018, 16:27
общий
22.08.2018, 16:31
Адресаты:
Почему EDX ? Он, вроде-бы, нигде не фигурирует
Результат EAX*EDI будет в паре регистров EDX:EAX
Т.о., если EDX не 0, то получаем переполнение двойного слова. Флаг С взведется только, если переполнится EDX:EAX
По причине использования регистра EDX в операции умножения, в нем нельзя хранить очередную цифру. Поэтому выбран EBX
При использовании регистра EDX, как хранителя цифры, получался в результате 0, т.к. регистр EDX после умножения обнулялся.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
401688
22
28.08.2018, 11:06
общий
Адресаты:
Цитата: Лысков Игорь Витальевич
При использовании регистра EDX, как хранителя цифры, получался в результате 0, т.к. регистр EDX после умножения обнулялся.
Всё ясно. Заработал мой арифмометр, как молодой. Благодаря вашей помощи. Теперь буду знакомить его с дробями (кнопкой ".").
давно
Посетитель
7438
7205
28.08.2018, 11:16
общий
Адресаты:
Дерзайте... Рекомендую освоить вещественные числа. Скажу сразу - просто не будет, но оно стоит того...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа