Скачать презентацию Лекции 27 28 Сложные типы данных массивы Скачать презентацию Лекции 27 28 Сложные типы данных массивы

lect27-28.ppt

  • Количество слайдов: 52

Лекции 27 – 28 Сложные типы данных: массивы, структуры, объединения Лекции 27 – 28 Сложные типы данных: массивы, структуры, объединения

Массивы Специальных средств описания массивов в программах на языке Ассемблер нет. Описание массива на Массивы Специальных средств описания массивов в программах на языке Ассемблер нет. Описание массива на язык Ассемблер выглядит как обычное описание элемента данных с инициализацией несколькими значениями или с помощью оператора dup. Вариант 1: arr 1 dw 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 Вариант 2 arr 2 dw arr 3 dw 10 dup(0) 10 dup(? )

Массивы Еще один способ описания массивов – это использование директив label и rept. Директива Массивы Еще один способ описания массивов – это использование директив label и rept. Директива label предназначена для описания меток определенного типа. Он не резервирует память под эти переменные. Директива rept предназначена для повторения определенного количества строк программы, расположенных между этой директивой и директивой endm. Пример описания массива с использованием директив label и rept: arr_w rept endm label 5 dw word 4040 h

Доступ к элементам массива Для доступа к элементам одномерного массива удобно использовать индексную адресацию Доступ к элементам массива Для доступа к элементам одномерного массива удобно использовать индексную адресацию со смещением: индекс * размер + смещение В данном режиме смещение – это адрес начала массива, индекс – номер элемента, размер – размер одного элемента массива (может быть 1, 2, 4 или 8). Пусть дан массив: arr dw 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 Синтаксис обращения к 4 -му элементу этого массива mov si, 4 mov ax, arr[si*2]

Доступ к элементам массива Рассмотренное ранее обращение к элементам массива возможно только если размер Доступ к элементам массива Рассмотренное ранее обращение к элементам массива возможно только если размер элементов массива составляет 1, 2, 4 или 8 байт. В противном случае вычисления смещение элемента массива необходимо осуществлять перемножив размер элемента массива на его индекс. Обращение к элементу осуществляется следующим образом: mov ax, ind mov cx, size mul cx mov dx, mas[ax]

Доступ к элементам массива Специальных средств для описания двумерных массивов в Ассемблере нет. Такие Доступ к элементам массива Специальных средств для описания двумерных массивов в Ассемблере нет. Такие массивы представляются в виде одномерных массивов: Двумерный Массив 12 34 56 Одномерный массив [1 2] [3 4] [5 6] Смещение элемента на позиции (i, j) в двумерном массиве вычисляется по формуле: Смещение = база + количество_элементов_в_строке*размер_элемента*i + размер_элемента*j

Доступ к элементам массива можно осуществить посредством базово -индексной адресации, в которой задействуется два Доступ к элементам массива можно осуществить посредством базово -индексной адресации, в которой задействуется два регистра: базовый и индексный. Пример для типа byte: mov eax, i mov ecx, n mul ecx mov esi, eax mov edi, j mov al, mas[esi][edi] Пример для типа word: mov eax, i mov ecx, n mul ecx shl eax, 1 mov esi, eax mov edi, j mov ax, mas[esi][edi*2]

Пример 1 Дан целочисленный массив (тип dword). Найти и вывести на экран максимальный элемент Пример 1 Дан целочисленный массив (тип dword). Найти и вывести на экран максимальный элемент массива. Размер массива и его элементы вводятся пользователем. Максимальный размер массива – 100 элементов. Программу реализовать в виде консольного приложения используя транслятор MASM 32.

Пример 1 include masm 32includemasm 32 rt. inc. data array num max buff mess Пример 1 include masm 32includemasm 32 rt. inc. data array num max buff mess 1 mess 2 mess 3 mess 4 endl dd dd dd db db db 100 dup(0) 10 0 20 dup(0) 'Input number of elements: ', 0 'Input elements: ', 0 dh, 0 ah, 0 'Max value: ', 0 'Incorrect number', 0 dh, 0 ah, 0

Пример 1. code start: call main inkey exit main proc cls call input. Array Пример 1. code start: call main inkey exit main proc cls call input. Array or eax, eax jnz next 0 invoke Std. Out, ADDR mess 4 ret next 0: call find. Max. Array invoke dwtoa, eax, ADDR buff invoke Std. Out, ADDR mess 3 invoke Std. Out, ADDR buff invoke Std. Out, ADDR endl ret main endp

Пример 1 input. Array proc invoke Std. Out, ADDR mess 1 invoke Std. In, Пример 1 input. Array proc invoke Std. Out, ADDR mess 1 invoke Std. In, ADDR buff, 20 invoke atol, ADDR buff cmp eax, 100 jle next 0 xor eax, eax ret next 0: mov num, eax invoke Std. Out, ADDR mess 2 xor ebx, ebx loop 0: invoke Std. In, ADDR buff, 20 invoke atol, ADDR buff mov array[ebx*4], eax inc ebx cmp ebx, num jnz loop 0 mov eax, 1 ret input. Array endp find. Max. Array proc xor ebx, ebx mov eax, array loop 0: mov edx, array[ebx*4] cmp edx, eax jl next 0 mov eax, edx next 0: inc ebx cmp ebx, num jnz loop 0 ret find. Max. Array endp end start

Пример 2 Найти в целочисленном массиве значение с максимальной суммой цифр в десятичной системе Пример 2 Найти в целочисленном массиве значение с максимальной суммой цифр в десятичной системе счисления. Размер массива и его элементы вводятся пользователем. Массив создается в динамической памяти. Найденный элемент и сумма его цифр выводится в формате: элемент – сумма. При реализации использовать передачу параметров в процедуры и локальные переменные.

Пример 2 include masm 32includemasm 32 rt. inc. data mess 0 mess 1 mess Пример 2 include masm 32includemasm 32 rt. inc. data mess 0 mess 1 mess 2 endl spac reslt db db db 'Input number of elements: ', 0 'Input elements: ', 0 dh, 0 ah, 0 'Max summa: ', 0 ' ', 0 dh, 0 ah, 0 ' - ', 0 'Result: ', 100 dup(0) buff db 20 dup(0) . code start: сls call main inkey exit

Пример 2 (процедура main) main proc push mov sub push call or jz mov Пример 2 (процедура main) main proc push mov sub push call or jz mov push call mov sub push call ebp, esp, 12 ebx, ebp ebx, 4 ebx Create. Array eax, eax exit 0 [ebp-8], eax [ebp-4] Input. Array ebx, ebp ebx, 12 ebx [ebp-8] [ebp-4] Find. Max ; Резервирование места под переменные ; Передача адреса ячейки куда ; необходимо записать количество ; элементов ; Проверка создания массива ; Если не создан, то выход ; Сохранение адреса массива ; Передача адреса массива в параметре ; Передача размера массива в параметре ; Передача адреса ячейки куда ; необходимо записать значение элемента ; с максимальной суммой цифр ; Передача адреса массива в параметре ; Передача размера массива в параметре

Пример 2 (процедура main) push call invoke pop invoke exit 0: add pop ret Пример 2 (процедура main) push call invoke pop invoke exit 0: add pop ret main endp eax [ebp-8] ; Передача адреса массива в параметре Free. Array ltoa, [ebp-12], ADDR buff sz. Cat. Str, ADDR reslt, ADDR spac eax ltoa, eax, ADDR buff sz. Cat. Str, ADDR buff, ADDR endl sz. Cat. Str, ADDR reslt, ADDR buff Std. Out, ADDR reslt esp, 12 ebp

Пример 2 (создание массива) Create. Array push mov invoke or jnz pop ret next Пример 2 (создание массива) Create. Array push mov invoke or jnz pop ret next 0: mov shl invoke pop ret Create. Array proc ebp, esp Std. Out, ADDR mess 0 Std. In, ADDR buff, 10 atol, ADDR buff eax, eax next 0 ebp 4 ebx, [ebp+8] [ebx], eax, 2 Alloc, eax ebp 4 endp ; Вывод приглашения ; Ввод строки ; Преобразование в число ; Проверка на ноль ; Запись в параметр по ссылке ; количество элементов ; Выделение памяти

Пример 2 (ввод элементов массива) Input. Array push mov invoke mov loop 0: push Пример 2 (ввод элементов массива) Input. Array push mov invoke mov loop 0: push invoke pop mov add loop pop ret Input. Array proc ebp, esp Std. Out, ADDR mess 1 ecx, [ebp+8] ebx, [ebp+12] ecx Std. In, ADDR buff, 10 atol, ADDR buff ecx [ebx], eax ebx, 4 loop 0 ebp 8 endp ; Вывод приглашения ; Получение количества элементов ; Получение адреса массива ; Ввод строки ; Преобразование в число ; Сохранение в массиве ; Переход на следующий элемент Альтернатива: mov [ebx][ecx*4]-4

Пример 2 (поиск значения) Find. Max push mov mov xor loop 0: push call Пример 2 (поиск значения) Find. Max push mov mov xor loop 0: push call cmp jg mov push pop next 1: add pop loop proc ebp, ecx, ebx, edi, edx, esp [ebp+8] [ebp+12] [ebp+16] edx ecx [ebx] Get. Summ edx, eax next 1 edx, eax [ebx] [edi] ebx, 4 ecx loop 0 mov pop ret Find. Max eax, edx ebp 12 endp ; Передача значения элемента ; Сравнение с текущим максимумом ; Сохранение нового максимума

Пример 2 (вычисление суммы) Get. Summ push mov push xor mov loop 1: xor Пример 2 (вычисление суммы) Get. Summ push mov push xor mov loop 1: xor div add or jnz mov pop pop ret Get. Summ proc ebp, edx ebx, eax, ecx, esp ebx [ebp+8] 10 edx, edx ecx ebx, edx eax, eax loop 1 eax, ebx edx ebp 4 endp ; Очистка регистра для хранения суммы ; Чтение значения параметра ; Очистка EDX ; Деление на 10 ; Прибавление к сумме остатка от деления ; Проверка на ноль ; Переход если не ноль

Пример 2 (уничтожение массива) Free. Array push mov invoke pop ret Free. Array end Пример 2 (уничтожение массива) Free. Array push mov invoke pop ret Free. Array end start proc ebp, esp eax, [ebp+8] Free, eax ebp 4 endp

Структуры Структура – это тип данных, состоящий из фиксированного числа элементов различных типов. Для Структуры Структура – это тип данных, состоящий из фиксированного числа элементов различных типов. Для использования структур в программе необходимо выполнить три действия: n Задать шаблон структуры. n Определить экземпляр структуры. n Организовать обращение к элементам структуры.

Структуры Описание шаблона структуры имеет вид: имя_структуры STRUC <описание полей> имя_структуры ENDS Здесь <описание Структуры Описание шаблона структуры имеет вид: имя_структуры STRUC <описание полей> имя_структуры ENDS Здесь <описание полей> представляет собой последовательность описания данных db, dw, dd и т. д. Пример описания структуры СТУДЕНТ student STRUC fio db 30 dup(“ “) year db 0 rate db 0 student ENDS

Структуры Для описания переменных структурного типа на языке Ассемблер используется следующая синтаксическая конструкция: [имя_переменной] Структуры Для описания переменных структурного типа на языке Ассемблер используется следующая синтаксическая конструкция: [имя_переменной] имя_структуры <[список_значений]> n n имя_переменной – идентификатор переменной данного структурного типа (если имя не указано, то просто будет выделен блок памяти для хранения значения). список_значений – заключенный в угловые скобки список начальных значений элементов структуры, разделенных запятыми. Если список указан не полностью, то все поля структуры для данной переменной инициализируются значениями из шаблона. Пример: st 1 student <‘Ivanov Ivan’, 1, 7> st 2 student <‘Petrov Petr’, 2, 8> st 3 student <> arr_st student 10 dup(<>)

Структуры Для доступа к отдельным элементам (полям) структуры в программе используется следующая синтаксическая конструкция: Структуры Для доступа к отдельным элементам (полям) структуры в программе используется следующая синтаксическая конструкция: адресное_выражение. имя_поля_структуры Здесь: n адресное_выражение – идентификатор переменной некоторого структурного типа или выражение в скобках в соответствии с правилами: [ Имя регистра + - ( Имя переменной + - ] Константа ) Константа имя_поля_структуры – имя поля из шаблона структуры Таким образом оператор вычисляет выражение: (адресное_выражение)+(имя_поля_структуры) n

Структуры Пример обращения к полям структуры: Первый способ: mov al, byte ptr st 1. Структуры Пример обращения к полям структуры: Первый способ: mov al, byte ptr st 1. year Второй способ: lea bx, st 2 mov al, byte ptr [bx]. year

Структуры Пример: вывести на экран список студентов средний балл которых больше или равен 6: Структуры Пример: вывести на экран список студентов средний балл которых больше или равен 6: student STRUC … student ENDS … st_list student 10 dup(<>) … mov bx, 32 lea di, st_list mov cx, 10 cycl: mov al, byte ptr [di]. rate cmp al, 6 jl next 0 ; вывод значения на экран next 0: add di, 32 loop cycl

Структуры Копирование одной структуры в другую (целиком или только часть) осуществляется с помощью команд Структуры Копирование одной структуры в другую (целиком или только часть) осуществляется с помощью команд пересылки строк: movsb, movsw или movsd Пример копирования структурной переменной st 1 в структурную переменную st 3: mov si, offset st 1 mov di, offset st 2 mov cx, 32 rep movsb

Объединения Объединение – тип данных, позволяющий трактовать одну и туже область памяти как имеющую Объединения Объединение – тип данных, позволяющий трактовать одну и туже область памяти как имеющую разные типы и имена. Описание объединения осуществляется практически также, как и описание структур: имя_объединения UNION <описание полей> имя_объединения ENDS

Объединения Пример: Пример описания переменной: mystruc STRUC pole 1 dw 0 pole 2 dw Объединения Пример: Пример описания переменной: mystruc STRUC pole 1 dw 0 pole 2 dw 0 mystruc ENDS un 1 myunion <> arr_un myunion 10 dup(<>) myunion UNION val 1 dd 0 val 2 mystruc<> myunion ENDS Обращение к полям объединения осуществляется аналогично обращению к полям структуры: mov eax, un 1. val 1 mov un 1. val 2. pole 1, ax

Пример Пользователь с клавиатуры вводит список студентов. О каждом студенте вводится следующая информация: ФИО Пример Пользователь с клавиатуры вводит список студентов. О каждом студенте вводится следующая информация: ФИО (строка 30 символов), курс и средний балл (целые числа размером 1 байт). Вывести на экран записи о студентах, средний балл которых не менее 6. include masm 32includemasm 32 rt. inc student STRUC fio db 30 dup(0) year db 0 rate db 0 student ENDS

Пример. data list num mess 0 mess 1 mess 2 mess 3 endl spac Пример. data list num mess 0 mess 1 mess 2 mess 3 endl spac buff student 20 dup(<>) dd 0 db 'Input number of students: ', 0 db 'FIO: ', 0 db 'YEAR: ', 0 db 'RATE: ', 0 db 0 dh, 0 ah, 0 db ' ', 0 db 31 dup(0)

Пример. code start: call inkey exit main cls call or jnz ret next 0: Пример. code start: call inkey exit main cls call or jnz ret next 0: lea mov loop 0: push mov cmp jl call next 1: add pop loop ret main endp main proc Input. List eax, eax next 0 ; Вызов процедуры ввода списка ; Проверка корректности ввода ; Если ввод корректен, то переход ; Выход, если ввод не корректен esi, list ecx, num ; Установка ESI на начало списка ; Запись в ECX количества элементов ecx al, BYTE PTR [esi+31] al, 6 next 1 Output. Student ; Сохранение ECX в стеке ; Заносим в AL средний балл текущего студента ; Сравниваем с 6 ; Если меньше, то переход ; Вызов процедуры вывода информации о студенте esi, 32 ecx loop 0 ; Переход к следующей записи ; Восстановление ECX ; Переход на следующую итерацию цикла ; Выход

Пример Input. List proc invoke Std. Out, ADDR mess 0 invoke Std. In, ADDR Пример Input. List proc invoke Std. Out, ADDR mess 0 invoke Std. In, ADDR buff, 30 invoke atol, ADDR buff cmp eax, 20 jle next 0 xor eax, eax ret next 0: mov num, eax lea edi, list mov ecx, eax loop 0: push ecx call Input. Student add edi, 32 pop ecx loop 0 mov eax, 1 ret Input. List endp ; Процедура ввода списка ; Вывод приглашения к вводу размера ; Ввод размера списка ; Преобразование в число ; Сравнение с 20 ; Если меньше или равно, то переход ; Установка кода ошибки ; Выход ; Запись в ячейку num размера списка ; Установка EDI на список ; Запись в ECX количества элементов ; Сохранение ECX в стеке ; Вызов процедуры ввода записи о студенте ; Переход к следующему элементу списка ; Восстановление ECX ; Цикл по всем элементам списка ; Установка кода успешного выполнения ; Выход

Пример Input. Student proc invoke mov invoke invoke mov ret Input. Student endp Std. Пример Input. Student proc invoke mov invoke invoke mov ret Input. Student endp Std. Out, ADDR mess 1 Std. In, edi, 30 sz. Len, edi dx, 2020 h [edi+eax-2], dx Std. Out, ADDR mess 2 Std. In, ADDR buff, 10 atol, ADDR buff BYTE PTR [edi+30], al Std. Out, ADDR mess 3 Std. In, ADDR buff, 10 atol, ADDR buff BYTE PTR [edi+31], al ; Вывод приглашения ввода ФИО ; Ввод строки в структуру ; Вычисление длины строки ; Замена перевода строки пробелами ; ; Вывод приглашения ввода курса ; Ввод курса ; Преобразование в число ; Запись в поле структуры ; Вывод приглашения ввода балла ; Ввод среднего балла ; Преобразование в число ; Запись в поле структуры ; Выход

Пример Output. Student proc invoke Std. Out, esi ; Вывод ФИО xor eax, eax Пример Output. Student proc invoke Std. Out, esi ; Вывод ФИО xor eax, eax ; Очистка EAX mov al, BYTE PTR [esi+30] ; Запись в AL курса invoke ltoa, eax, ADDR buff ; Преобразование в строку invoke sz. Cat. Str, ADDR buff, ADDR spac ; Добавление пробела invoke Std. Out, ADDR buff ; Вывод строки xor eax, eax ; Очистка EAX mov al, BYTE PTR [esi+31] ; Запись в AL сред. балл invoke ltoa, eax, ADDR buff ; Преобразование в строку invoke sz. Cat. Str, ADDR buff, ADDR endl ; Добавление перевода строки invoke Std. Out, ADDR buff ; Вывод строки ret ; Выход Output. Student endp end start

Пример 2 В бинарном файле содержится список записей о студентах. Каждая запись содержит: ФИО Пример 2 В бинарном файле содержится список записей о студентах. Каждая запись содержит: ФИО – строка 30 символов (+1 символ на хранение завершающего нуля), курс – целое число размером 1 байт, успеваемость – целое число размером 1 байт. Необходимо загрузить список из файла и вывести на экран. Далее у пользователя запрашивается поле и направление сортировки. Список упорядочивается и выводится на экран.

Пример 2 (описание структуры) include masm 32includemasm 32 rt. inc Student STRUC fio db Пример 2 (описание структуры) include masm 32includemasm 32 rt. inc Student STRUC fio db 31 dup(0) year db 0 rate db 0 Student ENDS ; Поле «ФИО» ; Поле «Номер курса» ; Поле «Успеваемость»

Пример 2 (сегмент данных). data mess 1 mess 2 mess 3 mess 4 mess Пример 2 (сегмент данных). data mess 1 mess 2 mess 3 mess 4 mess 5 mess 6 mess 7 fname endl spac arrptr arrnum buff delim db db db dd dd db db 'Input file name: ', 0 'Input sort type (1 - by fio, 2 - by year, 3 - by rate): ', 0 'Input sort direction (0 - ascending, !0 - descending): ', 0 'No file!', 0 dh, 0 ah, 0 'Incorrect file!', 0 dh, 0 ah, 0 'File read error!', 0 dh, 0 ah, 0 'Incorrect input!', 0 dh, 0 ah, 0 100 dup(0) 0 dh, 0 ah, 0 ' ', 0 0 0 100 dup(0) '----------------------------', 0 dh, 0 ah, 0

Пример 2 (программа – начало) start: cls ; Очистка экрана call main ; Вызов Пример 2 (программа – начало) start: cls ; Очистка экрана call main ; Вызов главной процедуры inkey ; Ожидание нажатия клавиши exit ; Завершение программы

Пример 2 (Процедура main – ввод имени файла и его проверка) main proc push Пример 2 (Процедура main – ввод имени файла и его проверка) main proc push mov invoke lea add mov invoke cmp jne invoke pop ret ebp, esp Std. Out, ADDR mess 1 Std. In, ADDR fname, 99 edx, fname eax, edx BYTE PTR [eax-2], 0 filesize, ADDR fname eax, -1 next 0 Std. Out, ADDR mess 4 ebp ; Настройка базы ; ; Вывод приглашения к вводу имени файла ; Ввод имени файла ; Установка EDX на имя файла ; Установка EAX на конец строки имени файла ; Запись завершающего нуля вместо n ; Определение размера файла ; Если файл существует, то ; переход на next 0 ; Вывод сообщения об отсутствии файла ; Восстановление EBP ; Завершение main ecx, 33 edx, edx ecx edx, edx next 1 Std. Out, ADDR mess 5 ebp ; Заносим в ECX размер структуры ; Очистка EDX ; Делим EDX: EAX на ECX ; Проверка остатка от деления на ноль ; Если ноль, то переход на next 1 ; Вывод сообщения о некорректном файле ; Восстановление EBP ; Завершение main next 0: mov xor div or jz invoke pop ret

Пример 2 (процедура main – загрузка списка и вывод на экран) next 1: invoke Пример 2 (процедура main – загрузка списка и вывод на экран) next 1: invoke or jnz invoke pop ret read_disk_file, ADDR fname, ADDR arrptr, ADDR arrnum ; Чтение файла eax, eax ; Проверка EAX на ноль next 2 ; Если не ноль, то переход на next 2 Std. Out, ADDR mess 6 ; Вывод сообщения об ошибке чтения ebp ; Восстановление EBP ; Завершение процедуры main mov xor div mov push call eax, DWORD PTR arrnum ecx, 33 edx, edx ecx DWORD PTR arrnum, eax DWORD PTR arrnum DWORD PTR arrptr Output. List next 2: ; Запись в EAX размера файла ; Запись в ECX размера структуры ; Очистка EDX ; Вычисление количества записей ; Запись количества записей ; Помещение в стек адреса списка ; Вызов процедуры вывода списка на экран

Пример 2 (процедура main – ввод параметров сортировки) invoke mov cmp jl cmp jg Пример 2 (процедура main – ввод параметров сортировки) invoke mov cmp jl cmp jg sub push jmp Std. Out, ADDR mess 2 Std. In, ADDR buff, 5 al, BYTE PTR buff al, 49 error 0 al, 51 error 0 al, 48 eax next 3 ; Вывод сообщения ввода поля сортировки ; Ввод номера поля сортировки ; Запись в AL номера поля сортировки ; Сравнение с 1 ; Если меньше, то переход на error 0 ; Сравнение с 3 ; Если больше, то переход на error 0 ; Вычитание кода нуля ; Сохранение поля сортировки в стеке ; Преход на next 3 invoke pop ret Std. Out, ADDR mess 7 ebp ; Вывод сообщения о некорректном вводе ; Восстановление EBP ; Завершение main invoke mov sub or pop Std. Out, ADDR mess 3 Std. In, ADDR buff, 5 al, BYTE PTR buff al, 48 al, al eax ; Вывод приглашения ввода направления ; Ввод направления сортировки ; Запись в AL направления сортировки ; Вычитание кода нуля ; Проверка на ноль ; Восстановление номера поля сортировки error 0: next 3:

Пример 2 (процедура main – передача процедуры сравнения при сортировке) next 4: next 5: Пример 2 (процедура main – передача процедуры сравнения при сортировке) next 4: next 5: ascsrt: next 6: next 7: jz cmp jnz push jmp cmp jnz push jmp push ascsrt al, 1 next 4 cmp. Fio. D callsrt al, 2 next 5 cmp. Year. D callsrt cmp. Rate. D callsrt al, 1 next 6 cmp. Fio. A callsrt al, 2 next 7 cmp. Year. A callsrt cmp. Rate. A ; Переход на ascstr, если сортировка по возрастанию ; Если сортировка не по полю «ФИО» , то ; переход по метке next 4 ; Занесение в стек адреса cmp. Fio. D ; Переход на сортировку ; Если сортировка не по полю «Курс» , то ; переход по метке next 5 ; Занесение в стек адреса cmp. Year. D ; Переход на сортировку ; Занесение в стек адреса cmp. Rate. D ; Переход на сортировку ; Если сортировка не по полю «ФИО» , то ; переход по метке next 6 ; Занесение в стек адреса cmp. Fio. A ; Переход на сортировку ; Если сортировка не по полю «Курс» , то ; переход по метке next 7 ; Занесение в стек адреса cmp. Year. A ; Переход на сортировку ; Занесение в стек адреса cmp. Rate. A

Пример 2 (процедура main – вызов сортировки и вывода упорядоченного списка на экран) callsrt: Пример 2 (процедура main – вызов сортировки и вывода упорядоченного списка на экран) callsrt: main push call invoke pop ret endp DWORD PTR arrnum DWORD PTR arrptr Sort. List DWORD PTR arrnum DWORD PTR arrptr Output. List Global. Free, arrptr ebp ; Передача количества элементов ; Передача адреса массива ; Вызов процедуры сортировки ; Передача количества элементов ; Передача адреса массива ; Вызов процедуры вывода списка ; Очистка памяти ; Восстановление EBP ; Завершение main

Пример 2 (процедура вывода списка) Output. List proc push mov mov ebp, esp ecx, Пример 2 (процедура вывода списка) Output. List proc push mov mov ebp, esp ecx, [ebp+12] esi, [ebp+8] push xor lea ecx esi ecx, ecx edi, buff loop 0: loop 1: lodsb or jz stosb inc jmp al, al exit 0 ecx loop 1 exit 0: mov neg add rep stosb al, 32 ecx, 30 pop mov add shl mov add stosd mov stosd invoke pop add loop invoke pop ret Output. List endp esi al, 32 ah, [esi+32] ah, 48 eax, 16 al, 32 ah, [esi+31] ah, 48 eax, 0 d 0 ah Std. Out, ADDR buff ecx esi, 33 loop 0 Std. Out, ADDR delim ebp 8

Пример 2 (сравнение по возрастанию ФИО) cmp. Fio. A proc push mov mov ebp, Пример 2 (сравнение по возрастанию ФИО) cmp. Fio. A proc push mov mov ebp, esp edi, [ebp+8] esi, [ebp+12] loop 0: ex_true: mov jmp eax, 1 exit 0 xor eax, eax pop ret endp ebp 8 ex_false: mov or jz cmp jz jg jmp al, [esi] ah, [edi] ax, ax ex_false al, al ex_false ah, ah ex_true al, ah next 0 ex_true ex_false inc jmp esi edi loop 0 next 0: exit 0: cmp. Fio. A

Пример 2 (сравнение по убыванию ФИО) cmp. Fio. A proc push mov mov ebp, Пример 2 (сравнение по убыванию ФИО) cmp. Fio. A proc push mov mov ebp, esp edi, [ebp+12] esi, [ebp+8] loop 0: ex_true: mov jmp eax, 1 exit 0 xor eax, eax pop ret endp ebp 8 ex_false: mov or jz cmp jz jg jmp al, [esi] ah, [edi] ax, ax ex_false al, al ex_false ah, ah ex_true al, ah next 0 ex_true ex_false inc jmp esi edi loop 0 next 0: exit 0: cmp. Fio. A

Сравнение по полю «Курс» cmp. Year. A proc push ebp mov ebp, esp mov Сравнение по полю «Курс» cmp. Year. A proc push ebp mov ebp, esp mov esi, [ebp+12] mov edi, [ebp+8] mov al, [esi+31] cmp al, [edi+31] jg ex_true xor eax, eax pop ebp ret 8 ex_true: mov eax, 1 pop ebp ret 8 cmp. Year. A endp cmp. Year. D proc push ebp mov ebp, esp mov esi, [ebp+12] mov edi, [ebp+8] mov al, [esi+31] cmp al, [edi+31] jl ex_true xor eax, eax pop ebp ret 8 ex_true: mov eax, 1 pop ebp ret 8 cmp. Year. D endp

Сравнение по полю «Успеваемость» cmp. Rate. A proc push ebp mov ebp, esp mov Сравнение по полю «Успеваемость» cmp. Rate. A proc push ebp mov ebp, esp mov esi, [ebp+12] mov edi, [ebp+8] mov al, [esi+32] cmp al, [edi+32] jg ex_true xor eax, eax pop ebp ret 8 ex_true: mov eax, 1 pop ebp ret 8 cmp. Rate. A endp cmp. Rate. D proc push ebp mov ebp, esp mov esi, [ebp+12] mov edi, [ebp+8] mov al, [esi+32] cmp al, [edi+32] jl ex_true xor eax, eax pop ebp ret 8 ex_true: mov eax, 1 pop ebp ret 8 cmp. Rate. D endp

Процедура обмена значений Swap. Vals proc push ebp mov ebp, esp sub esp, [ebp+16] Процедура обмена значений Swap. Vals proc push ebp mov ebp, esp sub esp, [ebp+16] mov edi, esp mov esi, [ebp+8] mov ecx, [ebp+16] rep movsb mov edi, [ebp+8] mov esi, [ebp+12] mov ecx, [ebp+16] rep movsb mov edi, [ebp+12] mov esi, esp mov ecx, [ebp+16] rep movsb add esp, [ebp+16] pop ebp ret 12 Swap. Vals endp ; Резервирование места под временный буфер ; Установка EDI на буфер ; Установка ESI на 1 -е значение ; Занесение в ECX размера ; Копирование ; Установка EDI на 1 -е значение ; Установка ESI на 2 -е значение ; Занесение в ECX размера ; Копирование ; Установка EDI на 2 -е значение ; Установка ESI на буфер ; Занесение в ECX размера ; Копирование ; Удаление буфера

Процедура сортировки - начало Sort. List proc push mov sub mov ebp, esp, 4 Процедура сортировки - начало Sort. List proc push mov sub mov ebp, esp, 4 [ebp-4], DWORD PTR 1 ; Резервирование места под флаг ; Инициализация флага cmp jnz mov mov dec [ebp-4], DWORD PTR 1 exit 0 [ebp-4], DWORD PTR 0 esi, [ebp+8] ecx, [ebp+12] ecx ; Проверка флага ; Если ноль, то переход на exit 0 ; Сброс флага ; Заносим в ESI адрес списка ; Заносим в ECX количество элементов ; На одну итерацию меньше push add push call pop or jz ecx esi esi, 33 esi DWORD PTR [ebp+16] esi eax, eax exloop ; Сохранение ECX ; Сохранение ESI ; Передача адреса 1 -й записи ; Вычисление адреса 2 -ой записи ; Передача адреса 2 -й записи ; Вызов процедуры сравнения ; Восстановление ESI ; Проверка EAX на ноль ; Если ноль, то переход на exloop 0: loop 1:

Процедура сортировки - продолжение push add push call pop mov esi DWORD PTR 33 Процедура сортировки - продолжение push add push call pop mov esi DWORD PTR 33 esi, 33 esi Swap. Vals esi [ebp-4], DWORD PTR 1 ; Сохранение ESI ; Передача размера структуры ; Передача адреса 1 -й записи ; Вычисление адреса 2 -й записи ; Передача адреса 2 -й записи ; Вызов процедуры обмена значений ; Восстановление ESI ; Установка флага add pop loop jmp esi, 33 ecx loop 1 loop 0 ; Переход к следующей записи ; Восстановление ECX ; Внутренний цикл ; Внешний цикл add pop ret endp esp, 4 ebp 12 ; Удаление флага exloop: exit 0: Sort. List