Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум на Исходниках.RU > Assembler > конвертация типов |
Автор: cupoma58 04.05.18, 09:49 |
Привет. Пытаюсь создать простой калькулятор (masm32). Знак "-" не вводится. Основной код готов, осталась конвертация: ... call GetWindowText ---> str с дисплея в eax ... call str_dec_hex_bin_proc ... call bin_hex_dec_str_proc ... call SetWindowText ---> str на дисплей ... Возится с процедурами - лень. Подскажите - где подсмотреть готовые или, хотя-бы, по частям. ----------------------------- Подсказали две функции: GetDlgItemInt и SetDlgItemInt Правильно-ли я понял из описания: Eсли, при получении набранного на дисплее числа, вместо GetWindowText использовать GetDlgItemInt, то в ЕАХ уйдёт "bin" ? A, при добавлении на дисплей результата операции, вместо SetWinlowText использовать SetDlgItemInt, то в ЕАХ уйдёт "str" ? Если в общем: str --> GetWindowText --> bin --> SetDlgItemInt --> str ? ---------------------------- А главное - учитывают-ли эти функции символ "точка" как признак дробнoсти вводимого числа ? |
Автор: Qraizer 04.05.18, 12:45 |
GetDlgIntemInt() сразу возвращает число, при этом она учитывает "-" впереди, если он есть. SetDlgIntemInt() возвращает просто признак успеха. А что ей ещё возвращать-то? Но надо правильно указать последний параметр, иначе отрицательные числа будут восприняты неверно (или наоборот). Обе функции не работают с плавающей точкой, т.к. функции ОСовые и должны обслуживать любые программы, а плавающая точка сильно зависит от используемого в программах языка программирования. Готовые функции для преобразования несложно нагуглить, но интереснее написать. Там ничего сложного. Пробуй, поможем. |
Автор: Jin X 05.05.18, 07:05 |
Для преобразования чисел в строки можно использовать wsprintf из USER32.DLL (но он не понимает float - %f) или sprintf из MSVCRT.DLL (crt_sprintf в MSVCRT.INC для MASM32, %f понимает). Из строк в числа – atoi/atoi64/atol/atoll (integer), atof (float). См. MSDN. В MASM32 есть библиотека MASM32.LIB (MASM32.INC), там есть функции типа atodw/a2dw (для беззнаковых), atol (знаковые), atofp, fptoa/fptoa2 (float). Исходники в папке m32lib. |
Автор: cupoma58 15.05.18, 09:55 |
Цитата Jin X @ Благодарю, попробую. |
Автор: cupoma58 18.07.18, 08:13 |
Доделал графику арифмометра, добрался до преобразования типов: строка <--> дес.число <--> дв.код. Обнаружил подсказку (Р.Марек)и переделал её для целых положительных чисел (дес.число --> строка): <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> ;преобразуем число в строку: dec2asc proc ;выход: заполненный ascbuf pushad ;сохраняем все регистры общего назначения mov ebx,0Ah ;EBX = основание системы счисления mov eax,bincod ;EAX = число lea edi,ascbuf ;EDI = указатель на строку-результат xor esi,esi ;ESI = 0 - счетчик цифр в стеке conv: xor edx,edx ;сюда - остаток от деления - цифра div ebx ;делим ЕАХ на ЕВХ, частное в ЕАХ, остаток в EDX add dl,"0" ;преобразуем остаток в ASCII-символ и... push edx ;...запихиваем в стек inc esi ;увеличиваем счётчик цифр в стеке test eax,eax ;ЕАХ = 0 ? jnz conv ;если - нет, продолжаем cld ;сбрасываем флаг направления DF, запись вперёд write: pop eax ;выталкиваем цифры из стека stosb ;записываем byte из AL в буфер по адресу ES:EDI dec esi ;уменьшаем к-во оставшихся цифр test esi,esi ;ESI=0 ? jnz write ;если - нет, переходим к следующей цифре mov byte ptr [edi],0 ;заканчиваем строку 0-вым байтом popad ret dec2asc endp Есть одна непонятность: ASCII-символы накапливаются в EDX и сохраняются в стеке (для разворота). Почему их достают из EAX ? Судя по команде "stosb" - это не опечатка. И ещё один момент: поскольку числа целые, в арифметике я использую FIxxx, например: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> … fild var1 fild var2 fiadd(fisub,fimul,fidiv) ;error A2070: invalid instruction operands" fistp bincod ... Чем моему компилятору (masm32 v.11) не угодили эти команды ? |
Автор: Jin X 18.07.18, 19:20 |
Цитата cupoma58 @ Их достают не из EAX, а в EAX.Есть одна непонятность: ASCII-символы накапливаются в EDX и сохраняются в стеке (для разворота). Почему их достают из EAX ? Сохранили в стек, взяв из EDX, а из стека извлекли уже в EAX. Можно сделать так: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> но какой смысл писать 2 инструкции, когда можно обойтись одной?pop edx mov al,dl Регистр в инструкции pop необязательно должен соответствовать тому, что был в push. Иногда push+pop используется как замена mov. К примеру: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> илиpush [eax] pop [edx] ; [edx] = [eax], сделать mov [edx],[eax] нельзя <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> push 0 pop ds ; ds = 0, сделать mov ds,0 нельзя Добавлено Написано, что неверно заданы операнды. А где эти операнды? Полностью строку пришлите, как вы их используете. Если же вы загружаете 2 числа через fild, а потом хотите их сложить через fiadd, то так не делается. При загрузке (в т.ч. через fild) числа преобразуются в вещественные, так что складывать их нужно через faddp, как и любые другие вещественные числа. Только какой смысл использовать FPU, когда можно обойтись целочисленной арифметикой (mov, add)? А fild используется так: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> fild var1 ; загружаем целое var1 в st(0) (но оно всё равно преобразуется в вещественное) fiadd var2 ; добавляем к st(0) целое число var2 (оно предварительно преобразуется внутри процессора в вещественное) fistp result ; выводим целый результат в result |
Автор: cupoma58 12.09.18, 07:30 |
Цитата Jin X @ Цитата cupoma58 @ Их достают не из EAX, а в EAX.Есть одна непонятность: ASCII-символы накапливаются в EDX и сохраняются в стеке (для разворота). Почему их достают из EAX ? Сохранили в стек, взяв из EDX, а из стека извлекли уже в EAX. Можно сделать так: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> но какой смысл писать 2 инструкции, когда можно обойтись одной?pop edx mov al,dl Регистр в инструкции pop необязательно должен соответствовать тому, что был в push. Иногда push+pop используется как замена mov. К примеру: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> илиpush [eax] pop [edx] ; [edx] = [eax], сделать mov [edx],[eax] нельзя <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> push 0 pop ds ; ds = 0, сделать mov ds,0 нельзя Добавлено Написано, что неверно заданы операнды. А где эти операнды? Полностью строку пришлите, как вы их используете. Если же вы загружаете 2 числа через fild, а потом хотите их сложить через fiadd, то так не делается. При загрузке (в т.ч. через fild) числа преобразуются в вещественные, так что складывать их нужно через faddp, как и любые другие вещественные числа. Только какой смысл использовать FPU, когда можно обойтись целочисленной арифметикой (mov, add)? А fild используется так: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> fild var1 ; загружаем целое var1 в st(0) (но оно всё равно преобразуется в вещественное) fiadd var2 ; добавляем к st(0) целое число var2 (оно предварительно преобразуется внутри процессора в вещественное) fistp result ; выводим целый результат в result Тема закрыта, арифмометр заработал (cupoma58.ru/assembler.html) |
Автор: Jin X 12.09.18, 14:25 |
cupoma58, поздравляю! p.s. Пожалуйста, не цитируйте такие большие блоки текста – это не несёт смысловой нагрузки, а только загромождает тему. |