push 0 ; Указатель на переменную для записи количества выведенных символов,
; в данном случае не нужен, поэтому в стек кладём 0
push 10h ; Количество выводимых символов
push offset prompt ; Адрес выводимой строки
push hStdOut ; Идентификатор устройства вывода
call WriteConsole ; Вызываем функцию
; Вводим строку
push 0 ; Зарезервированный параметр, в стек кладём 0
push offset slength ; Адрес переменной, куда будет записано количество введённых символов
push 256 ; Максимальное количество вводимых символов
push offset str ; Адрес для записи введённой строки
push hStdIn ; Идентификатор устройства ввода
call ReadConsole ; Вызываем функцию
; Выводим строку
push 0
push 0
push slength
push offset str
push hStdOut
call WriteConsole
; Задержка
push 1800h
call Sleep
push 0
call ExitProcess
end program
Процедура ввода целого числа в 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
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |


