ХАНДЫФАР

Функция ArrayCopyIfEx копирует элементы из первого массива во второй массив на основании условия, заданного пользовательской функцией, переданной через указатель. Пользовательская функция обязана сохранять регистры AX, BX, DX, SI и DI в стеке. Функция ArrayCopyIfEx автоматически выравнивает стек на 8 байт.

Параметры:

  1. Указатель на первый массив (источник).
  2. Указатель на второй массив (назначение).
  3. Указатель на пользовательскую функцию, которая определяет, должен ли элемент быть скопирован.
  4. Размер массива (количество элементов).

Возвращаемое значение:

  • CX: Количество скопированных элементов во втором массиве.

Состояние флагов:

  • Функция не изменяет состояние флагов.

Особенности:

  • Функция проходит по первому массиву и копирует элементы во второй массив, если они удовлетворяют условию, заданному пользовательской функцией.

  • Пользовательская функция должна возвращать ZF=1, если элемент должен быть скопирован, и ZF=0, если нет.

  • Функция не изменяет значения регистров, кроме CX.

  1. title Автор: Довгополов Евгений Сергеевич
  2. .286C
  3. .model small
  4. .stack 100h
  5. data segment public
  6. ____array__dw _1, 2, 3, 4, 5, 7, 8, 9
  7. ___________dw _10, 11, 12
  8. ____arrlen equ ($-array) / 2
  9. ____buffer_dw _arrlen dup(?)
  10. ____fmtout db__"[%d] \0"
  11. data ends
  12. code segment public
  13. ____assume _ds:data, cs:code
  14. ____include Handyfar.inc
  15. ____include Handymac.inc
  16. ____main proc
  17. ________call____SetDataSegment
  18. ________push____arrlen
  19. ________pushs___IsDivBy2
  20. ________pushs___es:[buffer]
  21. ________pushs___ds:[array]
  22. ________call____ArrayCopyIfEx
  23. ________leabx___ds:[buffer]
  24. ________xor_____si, si
  25. ____PrintArrayLoop:
  26. ________push____word ptr[bx+si]
  27. ________leaax___ds:[fmtout]
  28. ________call____PrintFormatString
  29. ________add_____sp, 2
  30. ________incw____si
  31. ________loop____PrintArrayLoop
  32. ________push____0
  33. ________call____ExitProcessEx
  34. ____main endp
  35. ____IsDivBy2 proc
  36. ________push____ax
  37. ________push____bx
  38. ________push____dx
  39. ________mov_____bx, 2
  40. ________cwd
  41. ________idiv____bx
  42. ________test____dl, dl
  43. ________pop_____dx
  44. ________pop_____bx
  45. ________pop_____ax
  46. ________ret
  47. ____IsDivBy2 endp
  48. code ends
  49. end main
Функция ArrayCopyIfEx копирует элементы из первого массива во второй массив на основании условия, заданного пользовательской функцией, переданной через указатель. Пользовательская функция обязана сохранять регистры AX, BX, DX, SI и DI в стеке. Функция ArrayCopyIfEx автоматически выравнивает стек на 8 байт.

Параметры:

  1. Указатель на первый массив (источник).
  2. Указатель на второй массив (назначение).
  3. Указатель на пользовательскую функцию, которая определяет, должен ли элемент быть скопирован.
  4. Размер массива (количество элементов).

Возвращаемое значение:

  • CX: Количество скопированных элементов во втором массиве.

Состояние флагов:

  • Функция не изменяет состояние флагов.

Особенности:

  • Функция проходит по первому массиву и копирует элементы во второй массив, если они удовлетворяют условию, заданному пользовательской функцией.

  • Пользовательская функция должна возвращать ZF=1, если элемент должен быть скопирован, и ZF=0, если нет.

  • Функция не изменяет значения регистров, кроме CX.

  1. title Автор: Довгополов Евгений Сергеевич
  2. .286C
  3. .model small
  4. .stack 100h
  5. data segment public
  6. ____array__dw _1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12
  7. ____arrlen equ ($-array) / 2
  8. ____buffer_dw _arrlen dup(?)
  9. ____fmtout db__"[%d] \0"
  10. data ends
  11. code segment public
  12. ____assume _ds:data, cs:code
  13. ____include Handyfar.inc___________; Подключаем файл с функциями
  14. ____include Handymac.inc___________; Подключаем файл с макросами
  15. ____main proc
  16. ________call____SetDataSegment_____; Вызываем процедуру SetDataSegment
  17. ________push____arrlen_____________; 4-й: Ложим на вершину стека длину массива
  18. ________pushs___IsDivBy2___________; 3-й: Ложим на вершину стека адрес функции IsDivBy2
  19. ________pushs___es:[buffer]________; 2-й: Ложим на вершину стека адрес массива buffer
  20. ________pushs___ds:[array]_________; 1-й: Ложим на вершину стека адрес массива array
  21. ________call____ArrayCopyIfEx______; Вызываем процедуру ArrayCopyIfEx(array, buffer, IsDivBy2, 12) := CX
  22. ________leabx___ds:[buffer]________; Загружаем адрес массива buffer в регистр ds:bx
  23. ________xor_____si, si_____________; Обнуляем регистр-индекс
  24. ____PrintArrayLoop:
  25. ________push____word ptr[bx+si]____; 2-й: Ложим на вершину стека значение в bx под индексом si
  26. ________leaax___ds:[fmtout]________; 1-й: Загружаем адрес строки формата fmtout в регистр ds:ax
  27. ________call____PrintFormatString__; Вызываем процедуру PrintFormatString(ax:fmtout, bx)
  28. ________add_____sp, 2______________; Выравниваем стек
  29. ________incw____si_________________; Увеличиваем индекс si на 2
  30. ________loop____PrintArrayLoop_____; Выполняем цикл пока регистр cx не равен 0
  31. ________push____0__________________; Ложим на вершину стека байтовое значение кода возврата
  32. ________call____ExitProcessEx______; Вызываем процедуру ExitProcess(0)
  33. ____main endp
  34. ____IsDivBy2 proc__________________; Начало процедуры IsDivBy2
  35. ________push____ax_________________; Обязательно сохраняем значение регистра ax в стеке
  36. ________push____bx_________________; Обязательно сохраняем значение регистра bx в стеке
  37. ________push____dx_________________; Обязательно сохраняем значение регистра dx в стеке
  38. ________mov_____bx, 2______________; Копируем число 2 в регистр bx
  39. ________cwd________________________; Выполняем знаковое расширение регистра dx
  40. ________idiv____bx_________________; Делим значение в регистре ax на bx
  41. ________test____dl, dl_____________; Проверяем значение на 0
  42. ________pop_____dx_________________; Обязательно выталкиваем значение из стека обратно в регистр dx
  43. ________pop_____bx_________________; Обязательно выталкиваем значение из стека обратно в регистр bx
  44. ________pop_____ax_________________; Обязательно выталкиваем значение из стека обратно в регистр ax
  45. ________ret________________________; Возврат из функции
  46. ____IsDivBy2 endp__________________; Конец процедуры IsDivBy2
  47. code ends
  48. end main
Made on
Tilda