- •Лекция 22
- •Массивы
- •Массивы
- •Доступ к элементам массива
- •Доступ к элементам массива
- •Доступ к элементам массива
- •Доступ к элементам массива
- •Пример 1
- •Пример 1
- •Пример 1
- •Пример 1
- •Пример 2
- •Пример 2
- •Пример 2 (процедура main)
- •Пример 2 (процедура main)
- •Пример 2 (создание массива)
- •Пример 2 (ввод элементов массива)
- •Пример 2 (поиск значения)
- •Пример 2 (вычисление
- •Пример 2 (уничтожение массива)
- •Структуры
- •Структуры
- •Структуры
- •Структуры
- •Структуры
- •Структуры
- •Структуры
- •Объединения
- •Объединения
- •Пример
- •Пример
- •Пример
- •Пример
- •Пример
- •Пример
- •Пример 2
- •Пример 2 (описание структуры)
- •Пример 2 (сегмент данных)
- •Пример 2 (программа – начало)
- •Пример 2 (Процедура main – ввод имени файла и его проверка)
- •Пример 2 (процедура main – загрузка списка и вывод на экран)
- •Пример 2 (процедура main – ввод параметров сортировки)
- •Пример 2 (процедура main – передача процедуры сравнения при
- •Пример 2 (процедура main – вызов сортировки и вывода
- •Пример 2 (сравнение по возрастанию ФИО)
- •Пример 2 (сравнение по убыванию ФИО)
- •Сравнение по полю «Курс»
- •Сравнение по полю «Успеваемость»
- •Процедура обмена
- •Процедура сортировки - продолжение
Пример 2 (процедура main – загрузка списка и вывод на экран)
next1: |
|
|
invoke |
read_disk_file, ADDR fname, ADDR arrptr, ADDR arrnum ;Чтение файла |
|
or |
eax, eax |
;Проверка EAX на ноль |
jnz |
next2 |
;Если не ноль, то переход на next2 |
invoke |
StdOut, ADDR mess6 |
;Вывод сообщения об ошибке чтения |
pop |
ebp |
;Восстановление EBP |
ret |
|
;Завершение процедуры main |
next2: |
|
|
mov |
eax, DWORD PTR arrnum |
;Запись в EAX размера файла |
mov |
ecx, 33 |
;Запись в ECX размера структуры |
xor |
edx, edx |
;Очистка EDX |
div |
ecx |
;Вычисление количества записей |
mov |
DWORD PTR arrnum, eax |
;Запись количества записей |
push |
DWORD PTR arrnum |
;Помещение в стек количества записей |
push |
DWORD PTR arrptr |
;Помещение в стек адреса списка |
call |
OutputList |
;Вызов процедуры вывода списка на экран |
Пример 2 (процедура main – ввод параметров сортировки)
|
invoke |
StdOut, ADDR mess2 |
;Вывод сообщения ввода поля сортировки |
|
invoke |
StdIn, ADDR buff, 5 |
;Ввод номера поля сортировки |
|
mov |
al, BYTE PTR buff |
;Запись в AL номера поля сортировки |
|
cmp |
al, 49 |
;Сравнение с 1 |
|
jl |
error0 |
;Если меньше, то переход на error0 |
|
cmp |
al, 51 |
;Сравнение с 3 |
|
jg |
error0 |
;Если больше, то переход на error0 |
|
sub |
al, 48 |
;Вычитание кода нуля |
|
push |
eax |
;Сохранение поля сортировки в стеке |
|
jmp |
next3 |
;Преход на next3 |
error0: |
|
|
|
|
invoke |
StdOut, ADDR mess7 |
;Вывод сообщения о некорректном вводе |
|
pop |
ebp |
;Восстановление EBP |
|
ret |
|
;Завершение main |
next3: |
|
|
|
|
invoke |
StdOut, ADDR mess3 |
;Вывод приглашения ввода направления |
|
invoke |
StdIn, ADDR buff, 5 |
;Ввод направления сортировки |
|
mov |
al, BYTE PTR buff |
;Запись в AL направления сортировки |
|
sub |
al, 48 |
;Вычитание кода нуля |
|
or |
al, al |
;Проверка на ноль |
|
pop |
eax |
;Восстановление номера поля сортировки |
|
|
|
|
Пример 2 (процедура main – передача процедуры сравнения при
|
сортировке)jz |
;Переход на ascstr, если сортировка по возрастанию |
||
|
|
|
ascsrt |
|
|
|
cmp |
al, 1 |
;Если сортировка не по полю «ФИО», то |
|
|
jnz |
next4 |
;переход по метке next4 |
|
|
push |
cmpFioD |
;Занесение в стек адреса cmpFioD |
|
|
jmp |
callsrt |
;Переход на сортировку |
next4: |
cmp |
al, 2 |
;Если сортировка не по полю «Курс», то |
|
|
|
jnz |
next5 |
;переход по метке next5 |
|
|
push |
cmpYearD |
;Занесение в стек адреса cmpYearD |
|
|
jmp |
callsrt |
;Переход на сортировку |
next5: |
push |
cmpRateD |
;Занесение в стек адреса cmpRateD |
|
|
|
jmp |
callsrt |
;Переход на сортировку |
ascsrt: |
cmp |
al, 1 |
;Если сортировка не по полю «ФИО», то |
|
|
|
jnz |
next6 |
;переход по метке next6 |
|
|
push |
cmpFioA |
;Занесение в стек адреса cmpFioA |
|
|
jmp |
callsrt |
;Переход на сортировку |
next6: |
cmp |
al, 2 |
;Если сортировка не по полю «Курс», то |
|
|
|
jnz |
next7 |
;переход по метке next7 |
|
|
push |
cmpYearA |
;Занесение в стек адреса cmpYearA |
|
|
jmp |
callsrt |
;Переход на сортировку |
next7: |
push |
cmpRateA |
;Занесение в стек адреса cmpRateA |
|
|
|
|
|
|
Пример 2 (процедура main – вызов сортировки и вывода
упорядоченного списка на экран)
callsrt:
push |
DWORD PTR arrnum |
;Передача количества элементов |
push |
DWORD PTR arrptr |
;Передача адреса массива |
call |
SortList |
;Вызов процедуры сортировки |
push |
DWORD PTR arrnum |
;Передача количества элементов |
push |
DWORD PTR arrptr |
;Передача адреса массива |
call |
OutputList |
;Вызов процедуры вывода списка |
invoke |
GlobalFree, arrptr |
;Очистка памяти |
pop |
ebp |
;Восстановление EBP |
ret |
|
;Завершение main |
main endp |
|
|
|
|
Пример 2 (процедура вывода |
|
||||
|
|
списка) |
|
mov |
al, 32 |
|
|
|
|
|
|||||
OutputList proc |
|
|
pop |
esi |
|
||
|
|
|
|
|
|||
|
|
push |
ebp |
|
mov |
ah, [esi+32] |
|
|
|
mov |
ebp, esp |
|
|
||
|
|
|
add |
ah, 48 |
|
||
|
|
mov |
ecx, [ebp+12] |
|
|
||
|
|
|
shl |
eax, 16 |
|
||
|
|
mov |
esi, [ebp+8] |
|
|
||
|
|
|
mov |
al, 32 |
|
||
loop0: |
|
|
|
||||
|
|
mov |
ah, [esi+31] |
|
|||
|
|
push |
ecx |
|
|
||
|
|
|
add |
ah, 48 |
|
||
|
|
push |
esi |
|
|
||
|
|
|
stosd |
|
|
||
|
|
xor |
ecx, ecx |
|
|
|
|
|
|
|
mov |
eax, 0d0ah |
|
||
|
|
lea |
edi, buff |
|
|
||
|
|
|
stosd |
|
|
||
loop1: |
|
|
|
|
|||
|
|
invoke |
StdOut, ADDR buff |
|
|||
|
|
lodsb |
|
|
|
||
|
|
|
|
pop |
ecx |
|
|
|
|
or |
al, al |
|
|
||
|
|
|
add |
esi, 33 |
|
||
|
|
jz |
exit0 |
|
|
||
|
|
|
loop |
loop0 |
|
||
|
|
stosb |
|
|
|
||
|
|
|
|
invoke |
StdOut, ADDR delim |
|
|
|
|
inc |
ecx |
|
|
||
|
|
|
pop |
ebp |
|
||
|
|
jmp |
loop1 |
|
|
||
|
|
|
ret |
8 |
|
||
exit0: |
|
|
|
||||
|
OutputList |
endp |
|
|
|||
|
|
mov |
al, 32 |
|
|
||
|
|
|
|
|
|
||
|
|
neg |
ecx |
|
|
|
|
|
|
add |
ecx, 30 |
|
|
|
|
|
|
rep stosb |
|
|
|
|
|
|
|
|
|
|
|
|
|
Пример 2 (сравнение по возрастанию ФИО)
cmpFioA |
proc |
|
|
|
|
||
|
|
push |
ebp |
|
|
|
|
|
|
mov |
ebp, esp |
ex_true: |
|
|
|
|
|
mov |
edi, [ebp+8] |
|
mov |
eax, 1 |
|
loop0: |
mov |
esi, [ebp+12] |
ex_false: |
jmp |
exit0 |
||
mov |
al, [esi] |
xor |
eax, eax |
||||
|
|
|
|||||
|
|
mov |
ah, [edi] |
exit0: |
|
|
|
|
|
or |
ax, ax |
|
pop |
ebp |
|
|
|
jz |
ex_false |
|
ret |
8 |
|
|
|
or |
al, al |
cmpFioA |
endp |
|
|
|
|
jz |
ex_false |
|
|
|
|
|
|
or |
ah, ah |
|
|
|
|
|
|
jz |
ex_true |
|
|
|
|
|
|
cmp |
al, ah |
|
|
|
|
|
|
jz |
next0 |
|
|
|
|
|
|
jg |
ex_true |
|
|
|
|
next0: |
jmp |
ex_false |
|
|
|
||
inc |
esi |
|
|
|
|||
|
|
|
|
|
|||
|
|
inc |
edi |
|
|
|
|
|
|
jmp |
loop0 |
|
|
|
|
|
|
|
|
|
|
|
Пример 2 (сравнение по убыванию ФИО)
cmpFioA |
proc |
|
|
|
|
||
|
|
push |
ebp |
|
|
|
|
|
|
mov |
ebp, esp |
ex_true: |
|
|
|
|
|
mov |
edi, [ebp+12] |
|
mov |
eax, 1 |
|
loop0: |
mov |
esi, [ebp+8] |
ex_false: |
jmp |
exit0 |
||
mov |
al, [esi] |
xor |
eax, eax |
||||
|
|
|
|||||
|
|
mov |
ah, [edi] |
exit0: |
|
|
|
|
|
or |
ax, ax |
|
pop |
ebp |
|
|
|
jz |
ex_false |
|
ret |
8 |
|
|
|
or |
al, al |
cmpFioA |
endp |
|
|
|
|
jz |
ex_false |
|
|
|
|
|
|
or |
ah, ah |
|
|
|
|
|
|
jz |
ex_true |
|
|
|
|
|
|
cmp |
al, ah |
|
|
|
|
|
|
jz |
next0 |
|
|
|
|
|
|
jg |
ex_true |
|
|
|
|
next0: |
jmp |
ex_false |
|
|
|
||
inc |
esi |
|
|
|
|||
|
|
|
|
|
|||
|
|
inc |
edi |
|
|
|
|
|
|
jmp |
loop0 |
|
|
|
|
|
|
|
|
|
|
|
Сравнение по полю «Курс»
cmpYearA |
proc |
|
cmpYearD |
proc |
|
|
|
push |
ebp |
push |
ebp |
||
|
mov |
|
ebp, esp |
mov |
|
ebp, esp |
|
mov |
|
esi, [ebp+12] |
mov |
|
esi, [ebp+12] |
|
mov |
|
edi, [ebp+8] |
mov |
|
edi, [ebp+8] |
|
mov |
|
al, [esi+31] |
mov |
|
al, [esi+31] |
|
cmp |
|
al, [edi+31] |
cmp |
|
al, [edi+31] |
|
jg |
|
ex_true |
jl |
|
ex_true |
|
xor |
|
eax, eax |
xor |
|
eax, eax |
|
pop |
|
ebp |
pop |
|
ebp |
|
ret |
|
8 |
ret |
|
8 |
ex_true: |
|
|
ex_true: |
|
|
|
|
mov |
|
eax, 1 |
mov |
|
eax, 1 |
|
pop |
|
ebp |
pop |
|
ebp |
|
ret |
|
8 |
ret |
|
8 |
cmpYearA |
endp |
|
cmpYearD |
endp |
|
|
|
|
|
|
|
|
|
Сравнение по полю «Успеваемость»
cmpRateA |
proc |
|
cmpRateD |
proc |
|
|
|
push |
ebp |
push |
ebp |
||
|
mov |
|
ebp, esp |
mov |
|
ebp, esp |
|
mov |
|
esi, [ebp+12] |
mov |
|
esi, [ebp+12] |
|
mov |
|
edi, [ebp+8] |
mov |
|
edi, [ebp+8] |
|
mov |
|
al, [esi+32] |
mov |
|
al, [esi+32] |
|
cmp |
|
al, [edi+32] |
cmp |
|
al, [edi+32] |
|
jg |
|
ex_true |
jl |
|
ex_true |
|
xor |
|
eax, eax |
xor |
|
eax, eax |
|
pop |
|
ebp |
pop |
|
ebp |
|
ret |
|
8 |
ret |
|
8 |
ex_true: |
|
|
ex_true: |
|
|
|
|
mov |
|
eax, 1 |
mov |
|
eax, 1 |
|
pop |
|
ebp |
pop |
|
ebp |
|
ret |
|
8 |
ret |
|
8 |
cmpRateA |
endp |
|
cmpRateD |
endp |
|
|
|
|
|
|
|
|
|
Процедура обмена
|
значений |
|
||
SwapVals |
proc |
|
|
|
|
push |
ebp |
|
|
|
mov |
|
ebp, esp |
|
|
sub |
|
esp, [ebp+16] |
;Резервирование места под временный буфер |
|
mov |
|
edi, esp |
;Установка EDI на буфер |
|
mov |
|
esi, [ebp+8] |
;Установка ESI на 1-е значение |
|
mov |
|
ecx, [ebp+16] |
;Занесение в ECX размера |
|
rep movsb |
;Копирование |
||
|
mov |
|
edi, [ebp+8] |
;Установка EDI на 1-е значение |
|
mov |
|
esi, [ebp+12] |
;Установка ESI на 2-е значение |
|
mov |
|
ecx, [ebp+16] |
;Занесение в ECX размера |
|
rep movsb |
;Копирование |
||
|
mov |
|
edi, [ebp+12] |
;Установка EDI на 2-е значение |
|
mov |
|
esi, esp |
;Установка ESI на буфер |
|
mov |
|
ecx, [ebp+16] |
;Занесение в ECX размера |
|
rep movsb |
;Копирование |
||
|
add |
|
esp, [ebp+16] |
;Удаление буфера |
|
pop |
|
ebp |
|
|
ret |
|
12 |
|
SwapVals |
endp |
|
|
|
|
|
|
|
|
|
|
Процедура сортировки - |
|
||
|
|
||||
|
|
начало |
|
|
|
SortList proc |
|
|
|
||
|
|
push |
ebp |
|
|
|
|
mov |
ebp, esp |
|
|
|
|
sub |
esp, 4 |
;Резервирование места под флаг |
|
|
|
mov |
[ebp-4], DWORD PTR 1 |
;Инициализация флага |
|
loop0: |
|
|
|
||
|
|
cmp |
[ebp-4], DWORD PTR 1 |
;Проверка флага |
|
|
|
jnz |
exit0 |
;Если ноль, то переход на exit0 |
|
|
|
mov |
[ebp-4], DWORD PTR 0 |
;Сброс флага |
|
|
|
mov |
esi, [ebp+8] |
;Заносим в ESI адрес списка |
|
|
|
mov |
ecx, [ebp+12] |
;Заносим в ECX количество элементов |
|
|
|
dec |
ecx |
;На одну итерацию меньше |
|
loop1: |
|
|
|
||
|
|
push |
ecx |
;Сохранение ECX |
|
|
|
push |
esi |
;Сохранение ESI |
|
|
|
push |
esi |
;Передача адреса 1-й записи |
|
|
|
add |
esi, 33 |
;Вычисление адреса 2-ой записи |
|
|
|
push |
esi |
;Передача адреса 2-й записи |
|
|
|
call |
DWORD PTR [ebp+16] |
;Вызов процедуры сравнения |
|
|
|
pop |
esi |
;Восстановление ESI |
|
|
|
or |
eax, eax |
;Проверка EAX на ноль |
|
|
|
jz |
exloop |
;Если ноль, то переход на exloop |
|
|
|
|
|
|
|