jnz  L1                                        ; Если ECX не равно 0, продолжаем цикл

  L2: pop  esi                                        ; Восстанавливаем значения использовавшихся регистров

  pop  ebx

  mov  esp, ebp                                ; Освобождаем стек

  pop  ebp                                        ; Восстанавливаем значение регистра EBP

  ret

InputNumber endp

Процедура вывода числа в 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

Процедура, проверяющая сбалансированность круглых и квадратных скобок в строке. Строка должна заканчиваться нулём. Для проверки сбалансированности открывающие скобки будем класть в стек, а при нахождении в строке закрывающей скобки будем извлекать из стека последнюю положенную туда открывающую скобку и проверять, что она соответствует закрывающей скобке. Будем считать, что скобок в тексте меньше, чем других символов, поэтому после сравнения делаем переход «если равно», считая, что это событие менее вероятно. При любом выходе из процедуры нужно очистить стек. Поскольку мы не можем заранее знать, сколько скобок будет туда положено и сколько извлечено, восстановление значения регистра ESP можно сделать только с помощью регистра EBP. Процедура возвращает значение через регистр EAX: если скобки сбалансированы, регистр EAX будет содержать значение истина (-1), в противном случае регистр EAX будет содержать значение ложь (0).

Brackets proc

  push  ebx                                ; Сохраняем регистры

  push  ebp

  mov  ebp, esp                        ; Сохраняем начальное значение регистра ESP

  mov  ebx, [ebp + 12]                ; Заносим в регистр EBX адрес начала строки

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17