На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
  
> конвертация типов , создание процедуры преобразования
    Привет. Пытаюсь создать простой калькулятор (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сти вводимого числа ?
      GetDlgIntemInt() сразу возвращает число, при этом она учитывает "-" впереди, если он есть. SetDlgIntemInt() возвращает просто признак успеха. А что ей ещё возвращать-то? Но надо правильно указать последний параметр, иначе отрицательные числа будут восприняты неверно (или наоборот). Обе функции не работают с плавающей точкой, т.к. функции ОСовые и должны обслуживать любые программы, а плавающая точка сильно зависит от используемого в программах языка программирования.
      Готовые функции для преобразования несложно нагуглить, но интереснее написать. Там ничего сложного. Пробуй, поможем.
        Для преобразования чисел в строки можно использовать 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.
          Цитата Jin X @

          Благодарю, попробую.
          Сообщение отредактировано: cupoma58 -
            Доделал графику арифмометра, добрался до преобразования типов: строка <--> дес.число <--> дв.код. Обнаружил подсказку (Р.Марек)и
            переделал её для целых положительных чисел (дес.число --> строка):
            ExpandedWrap disabled
              ;преобразуем число в строку:  
              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, например:
            ExpandedWrap disabled
                …
                fild  var1
                fild  var2
                fiadd(fisub,fimul,fidiv)  ;error A2070: invalid instruction operands"
                fistp bincod
                ...

            Чем моему компилятору (masm32 v.11) не угодили эти команды ?
              Цитата cupoma58 @
              Есть одна непонятность: ASCII-символы накапливаются в EDX и сохраняются в стеке (для разворота). Почему их достают из EAX ?
              Их достают не из EAX, а в EAX.
              Сохранили в стек, взяв из EDX, а из стека извлекли уже в EAX.
              Можно сделать так:
              ExpandedWrap disabled
                pop edx
                mov al,dl
              но какой смысл писать 2 инструкции, когда можно обойтись одной?
              Регистр в инструкции pop необязательно должен соответствовать тому, что был в push.
              Иногда push+pop используется как замена mov. К примеру:
              ExpandedWrap disabled
                push [eax]
                pop [edx]  ; [edx] = [eax], сделать mov [edx],[eax] нельзя
              или
              ExpandedWrap disabled
                push 0
                pop ds  ; ds = 0, сделать mov ds,0 нельзя


              Добавлено
              Цитата cupoma58 @
              Чем моему компилятору (masm32 v.11) не угодили эти команды ?
              Написано, что неверно заданы операнды. А где эти операнды?
              Полностью строку пришлите, как вы их используете.
              Если же вы загружаете 2 числа через fild, а потом хотите их сложить через fiadd, то так не делается. При загрузке (в т.ч. через fild) числа преобразуются в вещественные, так что складывать их нужно через faddp, как и любые другие вещественные числа. Только какой смысл использовать FPU, когда можно обойтись целочисленной арифметикой (mov, add)?
              А fild используется так:
              ExpandedWrap disabled
                fild var1  ; загружаем целое var1 в st(0) (но оно всё равно преобразуется в вещественное)
                fiadd var2  ; добавляем к st(0) целое число var2 (оно предварительно преобразуется внутри процессора в вещественное)
                fistp result  ; выводим целый результат в result
                Цитата Jin X @
                Цитата cupoma58 @
                Есть одна непонятность: ASCII-символы накапливаются в EDX и сохраняются в стеке (для разворота). Почему их достают из EAX ?
                Их достают не из EAX, а в EAX.
                Сохранили в стек, взяв из EDX, а из стека извлекли уже в EAX.
                Можно сделать так:
                ExpandedWrap disabled
                  pop edx
                  mov al,dl
                но какой смысл писать 2 инструкции, когда можно обойтись одной?
                Регистр в инструкции pop необязательно должен соответствовать тому, что был в push.
                Иногда push+pop используется как замена mov. К примеру:
                ExpandedWrap disabled
                  push [eax]
                  pop [edx]  ; [edx] = [eax], сделать mov [edx],[eax] нельзя
                или
                ExpandedWrap disabled
                  push 0
                  pop ds  ; ds = 0, сделать mov ds,0 нельзя


                Добавлено
                Цитата cupoma58 @
                Чем моему компилятору (masm32 v.11) не угодили эти команды ?
                Написано, что неверно заданы операнды. А где эти операнды?
                Полностью строку пришлите, как вы их используете.
                Если же вы загружаете 2 числа через fild, а потом хотите их сложить через fiadd, то так не делается. При загрузке (в т.ч. через fild) числа преобразуются в вещественные, так что складывать их нужно через faddp, как и любые другие вещественные числа. Только какой смысл использовать FPU, когда можно обойтись целочисленной арифметикой (mov, add)?
                А fild используется так:
                ExpandedWrap disabled
                  fild var1  ; загружаем целое var1 в st(0) (но оно всё равно преобразуется в вещественное)
                  fiadd var2  ; добавляем к st(0) целое число var2 (оно предварительно преобразуется внутри процессора в вещественное)
                  fistp result  ; выводим целый результат в result

                Тема закрыта, арифмометр заработал (cupoma58.ru/assembler.html)
                :victory:
                  cupoma58, поздравляю!
                  p.s. Пожалуйста, не цитируйте такие большие блоки текста – это не несёт смысловой нагрузки, а только загромождает тему.
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0356 ]   [ 15 queries used ]   [ Generated: 28.03.24, 19:08 GMT ]