Процедура вывода числа в 16-ричной системе счисления. Процедура получает один параметр – выводимое число. Для вывода всегда формируется строка из 8-ми шестнадцатеричных цифр с лидирующими нулями. Поскольку количество символов заранее известно, они будут сразу же записываться в строку с конца, и инвертировать строку не придётся. Процедура предназначена для использования в консольном приложении и предполагает, что идентификатор устройства ввода был получен основной программой и сохранён в переменной hStdOut.
digits db '0123456789abcdef' ; Массив шестнадцатеричных цифр OutputNumber proc push ebp ; Сохраняем в стеке значение регистра EBP mov ebp, esp ; Заносим в регистр EBP текущее значение вершины стека sub esp, 12 ; Выделяем в стеке место под формируемую строку push esi ; Преобразуем число в строку mov eax, [ebp + 8] ; Заносим в регистр EAX переданный параметр mov ecx, 8 ; Заносим в регистр ECX количество символов строки mov byte ptr [ebp - 1], 10 ; Добавляем в конец строки символы с кодами 13 и 10 для перевода курсора mov byte ptr [ebp - 2], 13 lea esi, [ebp - 3] ; Начиная с адреса [EBP - 3] будут заносится цифры L3: mov edx, eax ; Копируем значение регистра EAX в регистр EDX and edx, 1111b ; Получаем остаток от деления на 16 shr eax, 4 ; Делим исходное число на 16 mov dl, digits[edx] ; По полученному остатку от деления берём цифру ... mov [esi], dl ; ... и записываем её в строку dec esi ; Уменьшаем адрес, т.к. строка формируется с конца dec ecx ; Уменьшаем ECX на 1 jnz L3 ; Если ECX не равно 0, продолжаем цикл ; Выводим строку inc esi ; Регистр ESI указывает на начало строки push 0 push 0 push 10 push esi push hStdOut call WriteConsole pop esi mov esp, ebp ; Освобождаем стек pop ebp ; Восстанавливаем значение регистра EBP ret 4 ; Удаляем из стека переданный параметр и возвращаемся OutputNumber endp
Функция, находящая в одномерном массиве x сумму значений f(x[i]), где f – некоторая функция одного целочисленного аргумента, адрес которой передаётся через параметры. Функции используют соглашение о вызовах cdecl.
Sum proc push ebp mov ebp, esp push esi push edi mov ecx, [ebp + 8] ; Заносим в ECX первый параметр – количество элементов массива mov esi, [ebp + 12] ; Заносим в ESI второй параметр – адрес начала массива mov edi, [ebp + 16] ; Заносим в EDI третий параметр – адрес функции xor edx, edx ; Обнуляем регистр EDX L: push [esi] ; Кладём в стек элемент массива call edi ; Вызываем функцию, адрес которой находится в регистре EDI add esp, 4 ; Освобождаем стек add edx, eax ; Прибавляем результат функции к общей сумме add esi, 4 ; Переходим к следующему элементу массива dec ecx ; Уменьшаем значение регистра ECX на 1 jnz L ; Если ECX не равно 0, продолжаем цикл mov eax, edx ; Записываем полученную сумму в регистр EAX, ; через который должен возвращаться результат функции pop edi pop esi mov esp, ebp pop ebp ret Sum endp Sqr proc mov eax, [esp + 4] imul eax ret Sqr endp Negation proc mov eax, [esp + 4] neg eax ret Negation endp
Для вызова функции Sum будет использовать следующая последовательность команд.
push Sqr push offset a push na call Sum add esp, 12 mov sa, eax push Negation push offset a push na call Sum add esp, 12 mov sa, eax
Do'stlaringiz bilan baham: |