Процедура ввода целого числа в 16-ричной системе счисления. Процедура предназначена для использования в консольном приложении и предполагает, что идентификатор устройства ввода был получен основной программой и сохранён в переменной hStdIn.
InputNumber proc push ebp ; Сохраняем в стеке значение регистра EBP mov ebp, esp ; Заносим в регистр EBP текущее значение вершины стека sub esp, 16 ; Резервируем 16 байт. Вводимая строка может содержать до 8 цифр. ; 2 байта требуются для символов с кодами 13 и 10. Итого 10 байт. ; 4 байта нужно для целочисленной переменной, куда будет записываться количество ; введённых символов. Итого 14 байт. Но выделим 16 байт, т.е. 4 двойных слова push ebx ; Сохраняем значения важных регистров push esi ; Вводим строку push 0 lea eax, [ebp - 16] ; 4 байта по адресу [EBP – 16] предназначены для хранения количества введённых символов push eax push 10d lea eax, [ebp - 12] ; По адресу [EBP – 12] начинается память для вводимой строки push eax push hStdIn call ReadConsole ; Преобразуем строку в число xor eax, eax ; Обнуляем регистр EAX ... xor ebx, ebx ; ... и регистр EBX mov ecx, [ebp - 16] ; Заносим в регистр ECX количество введённых символов sub ecx, 2 ; Символы с кодами 13 и 10 обрабатывать не надо lea esi, [ebp - 12] ; Заносим в регистр ESI адрес начала строки test ecx, ecx ; Используем команду TEST для сравнения с нулём jz L2 ; Если ECX = 0, то завершаем работу процедуры L1: mov bl, [esi] ; Заносим в регистр BL текущий символ (три старших байта EBX ; содержат 0, т.к. ранее была команда XOR EBX, EBX) lea edx, [ebx - '0'] ; Заносим в регистр EDX разность между кодом текущего символа и кодом символа '0' cmp edx, 9 ; Сравниваем значение в регистре EDX с 9 ja M1 ; Если выше, то переходим к следующему сравнению sub bl, '0' ; Иначе получаем число из кода символа jmp M3 ; Переходим к действиям, учитывающим текущую цифру M1: lea edx, [ebx - 'a'] ; Заносим в регистр EDX разность между кодом текущего символа и кодом символа 'a' cmp edx, 'f' - 'a' ; Сравниваем значение в регистре EDX с 5 ja M2 ; Если выше, то переходим к следующему сравнению sub bl, 'a' - 10d ; Иначе получаем число из кода символа jmp M3 ; Переходим к действиям, учитывающим текущую цифру M2: lea edx, [ebx - 'A'] ; Заносим в регистр EDX разность между кодом текущего символа и кодом символа 'A' cmp edx, 'F' - 'A' ; Сравниваем значение в регистре EDX с 5 ja L2 ; Если выше, то завершаем процедуру. Результат не определён, ; т.к. был введён некорректный символ sub bl, 'A' - 10d ; Иначе получаем число из кода символа M3: sal eax, 4 ; Умножаем EAX на 16 add eax, ebx ; Прибавляем текущую цифру inc esi ; Переходим к следующему символу dec ecx ; Уменьшаем ECX на 1 jnz L1 ; Если ECX не равно 0, продолжаем цикл L2: pop esi ; Восстанавливаем значения использовавшихся регистров pop ebx mov esp, ebp ; Освобождаем стек pop ebp ; Восстанавливаем значение регистра EBP ret InputNumber endp
Do'stlaringiz bilan baham: |